【问题标题】:react / redux multiple actions反应/减少多个动作
【发布时间】:2016-10-26 07:54:28
【问题描述】:

在处理程序中一个接一个地调度多个(同步)动作是不是一个坏主意?

假设我有 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 对该信息感兴趣 - 它可以从动作 obj 中获取它。

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

谢谢。

【问题讨论】:

    标签: redux react-redux


    【解决方案1】:

    在我看来,以您描述的方式调度多个操作并没有错。

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

    这是一个取自实时代码的示例,我在单个操作中调度多个操作。 actions.modelSelect 函数返回一个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))
      }
    }
    

    【讨论】:

    • 所以我想我应该在某个时候进入 redux-thunk,似乎每个人都在使用它。谢谢。
    • redux-thunk 允许您将特殊类型的操作视为函数。这意味着您可以使用特定的操作相关逻辑来扩展普通操作。您给出的需要调度与另一个操作相关的操作的示例是 redux-thunk(或类似包)的绝佳用例。