就我而言,我有一家商店,如:
{
aa: {...},
bb: cc // the result of computing with aa
}
我需要同时更新aa
和bb
,但bb
需要获得aa
的最新计算。
这是一些代码(React.js):
onClick(e) {
const { dispatch, aa, bb } = this.props;
dispatch(updateAa());
dispatch(updateBb(aa)); // can not get the latest computation of aa, it is the last computation..
}
那么,这是否意味着我需要在aa
的缩减器中获取bb
?
我怎么能这样做?
希望有所帮助!,谢谢!
答案 0 :(得分:33)
请勿使用combineReducers.
示例强>
替换此代码
export const a = combineReducers({
app,
posts,
intl,
products,
pos,
cats,
});
带
export default (state = {}, action) => {
return {
app: app(state.app, action, state),
posts: posts(state.posts, action, state),
intl: intl(state.intl, action, state),
products: products(state.products, action, state),
pos: pos(state.pos, action, state),
cats: cats(state.cats, action, state),
};
};
reducer就像
const reducer = (state = initialState, action, root) => {....}
答案 1 :(得分:14)
有几种可能性,但鉴于代码含糊不清,很难说哪种方法最好。
props
的形式发送给您的组件。在此工作流程中,aa
和bb
将分别由选择器函数生成,而不是存储在该商店中。aa
之外更新bb
和combineReducers
的缩减器,以便它可以看到整个状态,而不是缩小到aa
的状态, bb
。updateAa
和updateBb
调用的帮助程序,并在每个操作中传递足够的信息以进行计算。答案 2 :(得分:8)
正如David L. Walsh所说,可能你应该以更合理的方式构建减速器。
但如果您仍然认为自己需要它,可以使用thunk中间件。 (https://github.com/gaearon/redux-thunk) Redux Thunk中间件允许您编写返回函数而不是动作的动作创建者。
Redux Thunk为您提供了一种读取Redux商店当前状态的方法。除了dispatch之外,它还将getState作为第二个参数传递给你从thunk action creator返回的函数。
export function action() {
return function(dispatch, getState){
const state = getState()
dispatch({
type: "ACTION_WITH_SOME_PART_OF_STATE,
some_part_of_state: state.some_part
})
}
}
答案 3 :(得分:5)
问问自己是否正确构建了减速器。如果a和b不是彼此独立的,为什么它们是单独的减速器?我会尝试将它们合并为一个减速器。
答案 4 :(得分:0)
根据谢赫·阿卜杜勒·瓦希德(Sheikh Abdul Wahid)的回答,我必须进行以下修改才能使其与history
和connected-react-router
一起使用:
在()
之后的connectRouter(history)
import { connectRouter } from 'connected-react-router'
const createRootReducer = (history) => {
return (state = {}, action) => {
return {
...reducers,
router: connectRouter(history)(),
...rest of reducers
}
}
}
答案 5 :(得分:0)
如果这是您的常用用例,则可以尝试编写自己的函数,以根据需要official Redux documentation推荐根据需求组合减速器:
类似地,如果sliceReducerA恰好需要sliceReducerB的状态切片中的某些数据来处理特定操作,或者sliceReducerB恰好需要整个状态作为参数,那么CombineReducers不会自行处理。这可以通过编写一个自定义函数来解决,该函数知道在这些特定情况下将所需数据作为附加参数传递,例如:
text.text = "";
我强烈建议您阅读this documentation page,其中还有其他一些建议在减速器之间共享数据,甚至可以将function combinedReducer(state, action) {
switch (action.type) {
case 'A_TYPICAL_ACTION': {
return {
a: sliceReducerA(state.a, action),
b: sliceReducerB(state.b, action)
}
}
case 'SOME_SPECIAL_ACTION': {
return {
// specifically pass state.b as an additional argument
a: sliceReducerA(state.a, action, state.b),
b: sliceReducerB(state.b, action)
}
}
case 'ANOTHER_SPECIAL_ACTION': {
return {
a: sliceReducerA(state.a, action),
// specifically pass the entire state as an additional argument
b: sliceReducerB(state.b, action, state)
}
}
default:
return state
}
}
用于简单操作,并针对特殊情况使用其他定制减速器。
希望这些选项对您有所帮助!
答案 6 :(得分:-1)
如果某个reducer需要来自另一个reducer的某些数据,那么一个简单的解决方案是将它们合并到单个reducer中。 就我而言,我需要来自另一个化简器的一些数据,并且很难管理它们,因此最终将它们合并。