带打字稿的Redux-在不同的reducer中处理相同的动作

时间:2019-09-17 16:14:43

标签: typescript redux

据我所知,redux的优点之一是当一个动作被分派时,几个化简器可以响应该动作,每个变器都执行自己的逻辑。问题是当我们必须将redux和typescript结合在一起时。

如果我们从example中选取official site of redux,则可以看到它遵循一定的模式,根据它们在应用程序中的作用将动作和缩减器分开。

chatReducer 仅接受属于 ChatActionTypes

的操作
export const SEND_MESSAGE = "SEND_MESSAGE";
export const DELETE_MESSAGE = "DELETE_MESSAGE";

interface SendMessageAction {
  type: typeof SEND_MESSAGE;
  payload: Message;
}

interface DeleteMessageAction {
  type: typeof DELETE_MESSAGE;
  meta: {
    timestamp: number;
  };
}

export type ChatActionTypes = SendMessageAction | DeleteMessageAction;
export function chatReducer(
  state = initialState,
  action: ChatActionTypes
): ChatState {
  switch (action.type) {
    case SEND_MESSAGE:
      return {
        messages: [...state.messages, action.payload]
      };
    case DELETE_MESSAGE:
      return {
        messages: state.messages.filter(
          message => message.timestamp !== action.meta.timestamp
        )
      };
    default:
      return state;
  }
}

systemReducer 将仅接受属于 SystemActionTypes

的操作
export const UPDATE_SESSION = "UPDATE_SESSION";

interface UpdateSessionAction {
  type: typeof UPDATE_SESSION;
  payload: SystemState;
}

export type SystemActionTypes = UpdateSessionAction;
export function systemReducer(
  state = initialState,
  action: SystemActionTypes
): SystemState {
  switch (action.type) {
    case UPDATE_SESSION: {
      return {
        ...state,
        ...action.payload
      };
    }
    default:
      return state;
  }
}

现在的问题是,当我们想在几个化简器中使用相同的动作时我们该怎么做。 假设除了在chatReducer中处理“ SEND_MESSAGE”之外,我们还想在systemReducer中对其进行响应,那么在不破坏模式的情况下最佳实践/正确方法是什么? (SEND_MESSAGE的类型确实是ChatActionTypes,而systemReducer仅接受SystemActionTypes)

1 个答案:

答案 0 :(得分:1)

  

reducer 将仅接受属于 action

的操作

不! Redux减速器接收所有操作,并发送到商店。然后由您来处理其中的一些。

该示例使用ChatActionTypesSystemActionTypes键入其reducers操作,以确保您仅处理这些类型的操作。

因此,在您的情况下,您必须扩大操作类型以处理其他操作。

  

在不破坏模式的情况下,最佳实践/正确方法是什么?

好吧,我想使用一种将所有动作分组的类型。

type StoreAction = ChatActionTypes | SystemActionTypes;

然后在所有减速器中使用它。

export function chatReducer(
  state = initialState,
  action: StoreAction
): ChatState;

export function systemReducer(
  state = initialState,
  action: StoreAction
): SystemState;

您的减速器会执行所有操作,这是任何键入都不会更改的事实。因此,我发现让减速器处理所有这些操作是一致的。

在这一点上,我认为这是一个优先问题,您可能希望将操作类型缩小到要使用的操作类型,或者使用对象的实际类型。

相关问题