我的Redux应用程序中有一种情况,我目前有3个独立的reducer来处理从api获取数据。我的一个减速器的一个例子是:
const INITIAL_STATE = {
data: [],
loading: false,
error: ''
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case GET_ALL_ORDERS_START:
return {
...state,
loading: true
};
case GET_ALL_ORDERS_SUCCESS:
return {
...state,
allOrders: action.payload,
loading: false
};
case GET_ALL_ORDERS_FAIL:
return {
...state,
loading: false,
error: action.payload
};
default:
return state;
}
};
注意加载和错误状态,这些在每个当前的reducer中都是相同的,并且将用于我编写的任何后续的reducer,包括从api中获取数据。
我想添加一个仅用于加载和错误状态的reducer。其他3个将存储数据。
这会给我:
数据缩减器x 3
const INITIAL_STATE = {
data: []
// any other state in the future
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case GET_ALL_ORDERS_SUCCESS:
return {
...state,
allOrders: action.payload
};
default:
return state;
}
};
加载/错误减少器(处理整个应用程序的加载/错误)
const INITIAL_STATE = {
loading: false,
error: ''
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case GET_ALL_ORDERS_START:
return {
...state,
loading: true
};
case GET_ALL_ORDERS_SUCCESS:
return {
...state,
loading: false
};
case GET_ALL_ORDERS_FAIL:
return {
...state,
loading: false,
error: action.payload
};
default:
return state;
}
};
正如您所看到的,这意味着GET_ALL_ORDER_SUCCESS操作类型将在2个单独的reducer中使用。我的问题是,这样可以吗?还是违反惯例?
非常感谢提前。
答案 0 :(得分:19)
我觉得这很好。没有地方可以说动作和减速器具有1:1映射。事实上,Redux的创建者明确表示它们之间没有任何关系,许多减速器可以对单个动作做出反应,单个减速器可以对多个动作做出反应。
我认为他说得最好:https://github.com/reduxible/reduxible/issues/8
推文:https://twitter.com/dan_abramov/status/691608868628119552
答案 1 :(得分:4)
我是否可以在两个或多个单独的化简器中使用相同的动作类型名称,也遇到了类似的问题,如果没有非常特殊的情况,答案肯定不是。
为什么不呢?
即使我们在分派动作时将所有reducer称为它们的switch case语句,也通过combinedReducers函数将它们组合后,分别编写了reducer。
减速器一:
export const postReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case "SET_DATA":
const { posts } = action.payload;
return {
...state,
posts: posts,
};
}
};
减速器二:
export const commentReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case "SET_DATA":
const { comments } = action.payload;
return {
...state,
comments: comments,
};
}
};
所以当我们调度一个类型为SET_DATA的动作时,两个reducer都会被调用 如果有效载荷值为
{
comments: ['comment one', 'comment two']
}
post reducer会将其post设置为undefined。
一个更好的解决方案是命名这样的类型:
case "SET_POST_DATA":
case "SET_COMMENT_DATA":
避免两个减速器动作之间发生冲突。
惯例是,当调用动作时,只有一个reducer负责回答该动作,否则会引起其他开发人员的误解