Redux 是一个流行的状态管理库,常被用于 React 应用程序中。但是,在构建更大型的应用程序时,仅仅只有一个 reducer 是远远不够的。因此,本文将探讨如何处理多个 reducer 之间的协作关系。
Reducer 的基础
在开始探讨多个 reducer 之间的协作关系之前,我们必须要先了解 reducer 的基础知识。
Reducer 是一个纯函数,接收当前状态对象和一个 action 对象作为参数,并返回新的状态对象。在 Redux 中,它负责更新应用程序的 state。例如,假设我们的应用程序有一个 counter,可以通过以下 reducer 实现递增:
function counterReducer(state = 0, action) { switch(action.type) { case 'INCREMENT': return state + 1 default: return state } }
我们可以通过 combineReducers
函数将多个 reducer 合并成一个 reducer。它接受一个对象作为参数,其中每个属性都是一个单独的 reducer,与状态树的相应属性相匹配:
import { combineReducers } from 'redux' const rootReducer = combineReducers({ counter: counterReducer, todos: todosReducer }) export default rootReducer
此时,我们的应用程序可以同时管理 counter
和 todos
两个状态。
处理多 reducer 协作
假设我们的应用程序中还有一个新的数据源 filter
,用于存储用户选择的过滤条件。我们可能会想要一个新的 reducer 来处理这个功能,例如:
function filterReducer(state = 'ALL', action) { switch (action.type) { case 'SET_FILTER': return action.filter default: return state } }
如果我们将这个 reducer 与现有的 counterReducer
和 todosReducer
组合起来,我们将拥有一个包含多个 reducer 的根 reducer,但它们都是互相独立的。 这意味着,每个 reducer 都可以分别处理它自己的状态,但它们不能直接相互协作。
那么,如何让这些 reducer 相互协作呢?一个常见的方法是“派发”一个 action 给多个 reducer 处理。让我们看看应用程序的典型状态树:
{ counter: 5, todos: [ { id: 1, text: 'todo1', completed: true }, { id: 2, text: 'todo2', completed: false } ], filter: 'ALL' }
假设用户要将过滤器设置为 'COMPLETED'。我们可以创建一个 SET_FILTER
action,然后将它派发给 filterReducer
以更新 filter
状态。这个 action 也可以被传递给 todosReducer
,然后它可以根据 filter
状态过滤出与之匹配的有效项。
-- -------------------- ---- ------- -------- ------------------ - --- ------- - ------ ------------- - ---- ----------- ------ ---------- - --- ------------- ----- ------------ ---------- ----- -- ---- -------------- ------ -------------- -- ------- --- --------- - - -------- ---------- --------------- - - ---- - ---- ------------- ------ ---------------------- -------------- -- --------- -------- ------ ----- - - -------- ---------------------- ------- - -------------- - ---- ------ ------ ----- ---- ------------ ------ ----------------- -- --------------- ---- --------- ------ ----------------- -- ---------------- -------- ----- --- -------------- ------- ------------ - -
为了简化代码,本例中假设 todosReducer
函数接受状态数组和 action 作为参数,并且使用一个 handleSetFilter
函数来处理过滤逻辑。
还有一个需要注意的地方是,当派发 action 给多个 reducer 时,我们需要确保 action 下传下去的状态是经过前一个 reducer 更新过的,而不是原来的状态。这可以通过在派发过滤器 action 时传递整个状态树来实现:
function setFilter(filter) { return { type: 'SET_FILTER', filter } } // ... store.dispatch(setFilter('COMPLETED', store.getState()))
第二个参数 store.getState()
表示在之前 reducer 更新后的状态。
总结
Redux 的能力不仅限于一个 reducer。当构建更大型的应用程序时,我们可以将多个 reducer 组合成根 reducer,并通过相互协作来更新状态。在派发 action 给多个 reducer 时,我们需要确保下传的状态是经过相应 reducer 更新过的。希望本文对您有所帮助,谢谢。
示例代码
-- -------------------- ---- ------- -------- -------------------- - -- ------- - ------------------- - ---- ------------ ------ ----- - - -------- ------ ----- - - -------- ------------------ - --- ------- - ------ ------------- - ---- ----------- ------ ---------- - --- ------------- ----- ------------ ---------- ----- -- ---- -------------- ------ -------------- -- ------- --- --------- - - -------- ---------- --------------- - - ---- - ---- ------------- ------ ---------------------- -------------- -------- ------ ----- - - -------- ------------------- - ------ ------- - ------ ------------- - ---- ------------- ------ ------------- -------- ------ ----- - - -------- ---------------------- ------- - -------------- - ---- ------ ------ ----- ---- ------------ ------ ----------------- -- --------------- ---- --------- ------ ----------------- -- ---------------- -------- ----- --- -------------- ------- ------------ - - ----- ----------- - ----------------- -------- --------------- ------ ------------- ------- ------------- -- ----- ----- - ------------------------ -------- ----------------- - ------ - ----- ------------- ------ - - ------------------------------------- ------------------
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64f5b584f6b2d6eab3e8a077