我正在寻找一种方法,在输入(根)减速器时为每个动作添加一些参数。
快速举例,让我假设我有userState
,其中包含当前已登录的用户,甚至可能处于某种子状态。
rootState
|
+-------------------------------------+
| |
userState +----+-----+
| | |
+---+-----------+ ... salesState
| |
... currentlySignedInUserState
为了在另一个reducer(例如salesReducer
)中执行一个动作,我需要拥有当前已登录的用户,这个用户不是很容易获得(处于兄弟状态或更糟糕状态)所以我必须拦截在根状态中的操作,从currentlySignedInUserState
读取userState
,将用户添加到操作有效负载,并使用更改的有效负载重新发出操作。
case SALES_ACTIONS.ADD_SALE:
return Object.assign({}, state, {
let payload = Object.assign({}, action.payload, {
userName: state.user.signedIn.name
});
sales: salesReducer(state.sales, {
type: SALES_ACTION.ADD_SALE,
payload
});
});
这变得一团糟,并阻止我使用combineReducers
,因为我必须在我自己制作的根减速器中转发每一个动作。
所以我提出了这样的想法:只需将用户添加到每个操作进入根减速器,然后只是combineReducers
。
这是一种被接受的方法,如果是这样,有没有办法扩展combineReducers
以便它需要额外的有效载荷参数(我在考虑redux-reuse,但我不确定是否会做我想到的事情。)
如果没有,我的替代方案是什么?
答案 0 :(得分:3)
您可以使用从状态获取userName
的简单middleware,并将其作为meta
数据添加到所有操作,除非signedIn
。您可以添加其他条件,例如应跳过的特定操作。
我更喜欢将其他数据添加为meta
,而不是有效负载。
我已经提出了两种方法来增强行动。
(未经测试的)代码:
const middleware = ({ getState }) => next => action => {
const state = getState();
if(!state.user.signedIn) { // if not signed in skip
return next(action);
}
const userName = state.user.signedIn.name;
/** add userName using assign **/
const meta = Object.assign({}, action.meta, { userName });
const newAction = Object.assign({}, action, { meta });
/**********************/
/** or add userName using object spread **/
const newAction = {
...action,
meta: { ...action.meta, username }
};
/**********************/
next(newAction);
};