在 Redux 中,通常我们会使用多个 reducer 来管理应用的状态,每个 reducer 负责管理应用中的不同领域的数据。但是,当应用变得复杂且数据多源时,我们需要将这些 reducer 的状态进行合并,以方便我们对全局状态进行管理。
下面,我们将介绍一种在 Redux 中处理多个 reducer 的 state 合并问题的方法。
使用 combineReducers 函数
Redux 为我们提供了 combineReducers
函数,该函数可以将多个 reducer 所管理的 state 进行合并。combineReducers
函数接受一个对象作为参数,该对象的键名与最终 state 中的字段名相同,而键值是一个 reducer 函数。
import { combineReducers } from 'redux'; const rootReducer = combineReducers({ todos: todosReducer, counter: counterReducer }); export default rootReducer;
上面的示例代码中,我们将 todosReducer
和 counterReducer
两个 reducer 合并为一个 rootReducer。这样,当我们 dispatch action 时,所有被合并的 reducer 都会接收到 action。
重构 reducer
为了更好地管理多源数据的情况,我们需要考虑将 reducer 中的 state 进一步拆分。如果我们将一个大的 reducer 拆分为多个小的 reducer,就可以实现更好的状态集中管理。
例如,我们拥有一个 todosReducer
和一个 visibilityFilterReducer
,我们可以将 todosReducer
拆分为 addTodoReducer
和 toggleTodoReducer
等。
-- -------------------- ---- ------- ----- -------------- - ------ - --- ------- -- - ------ ------------- - ---- --------- ------ - --------- - --- ---------- ----- ------------ ---------- ----- - -- -------- ------ ------ - -- ----- ----------------- - ------ - --- ------- -- - ------ ------------- - ---- ------------ ------ -------------- -- - -- -------- --- ---------- - ------ - -------- ---------- --------------- -- - ------ ----- --- -------- ------ ------ - -- ----- ------------ - ----------------- --------------- ----------------- ---
对于 visibilityFilterReducer
,我们可以用一个简单的 reducer 来处理。
const visibilityFilterReducer = (state = 'SHOW_ALL', action) => { switch (action.type) { case SET_VISIBILITY_FILTER: return action.filter; default: return state; } };
我们可以将 todosReducer
和 visibilityFilterReducer
再次合并为一个 rootReducer。
const rootReducer = combineReducers({ todosReducer, visibilityFilterReducer }); export default rootReducer;
总结
在 Redux 中,使用 combineReducers
函数可以将多个 reducer 的 state 进行合并,以方便我们对全局状态进行管理。为了更好地管理多源数据的情况,我们可以将 reducer 中的 state 进一步拆分,并将其合并为一个 rootReducer。这样,我们可以更加方便地管理全局状态,也可以使代码更加清晰易懂。
示例代码
完整的 Redux 应用示例代码可以在 Redux 官方文档 中找到。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64afd32b48841e9894bfd10f