Redux我可以在单独的reducer中使用一种动作类型吗?

mtw*_*let 22 redux react-redux

我的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;
  }
};
Run Code Online (Sandbox Code Playgroud)

注意加载和错误状态,这些在每个当前的reducer中是相同的,并且对于我编写的涉及从api获取数据的任何后续reducecer而言.

我想添加一个仅用于加载和错误状态的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;
  }
};
Run Code Online (Sandbox Code Playgroud)

加载/错误减少器(处理整个应用程序的加载/错误)

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;
  }
};
Run Code Online (Sandbox Code Playgroud)

如您所见,这意味着GET_ALL_ORDER_SUCCESS操作类型将在2个单独的Reducer中使用.我的问题是,这样可以吗?还是违反惯例呢?

提前谢谢了.

jul*_*ljk 30

我觉得这很好.没有地方可以说动作和减速器具有1:1映射.事实上,Redux的创建者明确表示它们之间没有关系,许多减速器可以对单个动作做出反应,单个减速器可以对多个动作做出反应.

我认为他说得最好:https://github.com/reduxible/reduxible/issues/8

鸣叫:https://twitter.com/dan_abramov/status/691608868628119552

相关SO:Redux:为什么不将动作和reducer放在同一个文件中?


Tor*_*bde 5

如果我可以在两个或多个单独的减速器中使用相同的动作类型名称,我有一个类似的问题,如果不是非常特殊的情况,答案肯定是否定的。

为什么不?

即使我们在通过 combineReducers 函数组合它们之后单独编写 reducer,当我们调度 action 时,所有 reducer 都被称为它们的 switch case 语句。

减速机一:

export const postReducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case "SET_DATA":
      const { posts } = action.payload;
      return {
        ...state,
        posts: posts,
      };
  }
};
Run Code Online (Sandbox Code Playgroud)

减速机二:

export const commentReducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case "SET_DATA":
      const { comments } = action.payload;
      return {
        ...state,
        comments: comments,
      };
  }
};
Run Code Online (Sandbox Code Playgroud)

因此,当我们调度类型为 SET_DATA 的操作时,两个减速器都将被调用,如果有效载荷值为

{
  comments: ['comment one', 'comment two'] 
}
Run Code Online (Sandbox Code Playgroud)

post reducer 将把它的 post 设置为 undefined。

更好的解决方案是像这样命名类型:

case "SET_POST_DATA":

case "SET_COMMENT_DATA": 
Run Code Online (Sandbox Code Playgroud)

避免两个减速器的动作发生碰撞。

约定是,当调用 action 时,只有一个 reducer 负责响应该 action,否则会引起其他开发人员的误解