反应/减少多个动作

react / redux multiple actions

在处理程序中一个接一个地分派多个(同步)操作是个坏主意吗?

假设我有 3 个按钮:buttonA、buttonB 和 buttonC。

对于我的第一个 reducer,知道单击了哪个按钮很重要,因此它可能看起来像这样:

const firstReducer = function(state = [], action){

    switch(action.type) {

        case types.BUTTON_A_CLICKED:
            console.log("button a was clicked");
            return state.concat("a");

        case types.BUTTON_B_CLICKED:
            console.log("button b was clicked");
            return state.concat("b");

        case types.BUTTON_C_CLICKED:
            console.log("button c was clicked");
            return state.concat("c");

        default:
            return state;
    }
}

但是我的第二个减速器只想知道什么时候点击了一个按钮(不关心哪个按钮)。我知道我可以这样做:

const secondReducer = function(state = [], action){

    switch(action.type) {

        case types.BUTTON_A_CLICKED:
        case types.BUTTON_B_CLICKED
        case types.BUTTON_B_CLICKED
            console.log("some button was clicked");
            return state.concat("button");

        default:
            return state;
    }
}

但是,如果我有 1000 个按钮怎么办?我可以让我的第二个减速器看起来像这样吗?:

const secondReducer = function(state = [], action){

    switch(action.type) {

        case types.BUTTON_CLICKED:
            console.log("some button was clicked");
            return state.concat("button");

        default:
            return state;
    }
}

并且从处理程序中为每次单击按钮分派 2 个操作, 一个用于特定按钮 (BUTTON_A_CLICKED) 和一位将军 (BUTTON_CLICKED)

onClickHandler(){
    dispatch({
            type: ACTION_TYPES.BUTTON_A_CLICKED,
        });

        dispatch({
            type: ACTION_TYPES.BUTTON_CLICKED,
        });

当然这是一个愚蠢的例子,我可以发送 BUTTON_CLICKED 并在动作数据中发送哪个按钮被点击,如果有任何 reducer 对该信息感兴趣 - 它可以从动作对象中获取它..

我执行的每次谷歌搜索都说要查看 redux thunk 或 saga,但我很想知道为什么(以及是否)按照我的建议去做是个坏主意。

谢谢。

在我看来,按照您描述的方式分派多个操作并没有错。

但是,当我想做类似的事情时,我遵循的模式是仅从处理程序分派一个动作,然后使用 redux-thunk 允许这个主要动作分派后续动作。

这是一个取自实时代码的示例,其中我从单个操作中分派多个操作。 actions.modelSelect 函数 returns a thunk:

actions.modelSelect = modelId => {
  return (dispatch, getState) => {
    const state = getState()
    const model = getModelById(state, modelId)
    dispatch({
      types,
      type: types.modelSelect,
      local: true,
      data: model
    })
    dispatch(actionHub.USAGE_LIST_FILE_SERVER())
    dispatch(actionHub.USAGE_LIST_FILE_MSAPI(modelId))
    dispatch(actionHub.BUILD_LIST(modelId))
  }
}