如何使用前一个动作的返回结果链接 redux 动作?

How to chain redux actions using returned result of the previous action?

我正在 React Native 中构建一个应用程序,并使用 Redux 和 redux-persist 作为设备数据库。

问题的症结在于,我如何 return redux 操作的结果,然后使用该数据调度另一个操作? 请继续阅读以了解更多信息具体细节。

用户可以创建自定义习惯类型。这样做时,我会发送一个动作来在商店中创建一种习惯类型(例如“运行”)。此操作会为习惯类型生成一个新的唯一 UUID。然后我想将这个新创建的习惯类型添加到例程中(例如“早上例程”),因此我需要接收回习惯类型的 UUID 并调用另一个调度将其添加到例程中。

我正在使用 immer 来简化我的 reducer 中的状态操作,并使用以下代码(简化示例):

import produce from "immer";

const userReducer = (state = initialState, action) => {
  switch (action.type) {
    case ADD_CUSTOM_HABIT_TYPE: {
      return produce(state, draftState => {
        const newHabitType = {
          id: generateUuid(),
          name,
        };

        draftState.customHabitTypes.push(newHabitType);

        return draftState;
      });
    }
  }
};

然后我在我的组件中发送它,像这样(简化):

dispatch({
  type: ADD_CUSTOM_HABIT_TYPE,
  name: "running",
});

我怎么能说,在创建这个新的习惯类型之后,调度另一个动作并将其添加到我的例程中?

我看过 redux-thunk and redux-saga,并花了数小时阅读这些内容并试图让 redux-thunk 工作,但无济于事。我确定这一定很简单,但我一头雾水,所以也许其他人也是如此,因此 post.

Actions 本身没有 return 数据,它们只是根据 reducer 中定义的规则改变存储的简单对象。两种可能的解决方案:

选项 A,创建复合操作。

const compositeAction = args => {
    return dispatch => {
        return someAsyncCall(args).then(response => {
           dispatch(addCustomHabitat(response))
           dispatch(followUpAction())
        }
    }
}

const addCustomHabitat = response => {
    return {
        type: "ADD_CUSTOM_HABIT_TYPE",
        data: response
    }
}

const followUpAction = () => {
    ...another action...
}

方案B,将第一个action的结果通过react-redux连接到调度组件,传递给第二个action

import {connect} from 'react-redux';

const MyReactComponent = props => {
    dispatch(addCustomHabitatTypeAction());

    if(props.customHabitatType !== undefined)
        dispatch(followUpAction(props.customHabitatType());

    return (
       ...JSX here...
    );
}

const mapStateToProps = state => {
    return {
        customHabitatType: state.userReducer.customHabitatType
    }
}

connect(mapStateToProps)(MyReactComponent);

希望对您有所帮助!请原谅我的缩写代码,如果您有任何问题,请告诉我。

一个非常简单的解决方案是在调度操作之前生成唯一 ID。

例子

const newHabitType = {
  id: generateUuid(),
  name,
};

dispatch({
  type: ADD_CUSTOM_HABIT_TYPE,
  habit: newHabitType,
});

dispatch({
  type: ADD_CUSTOM_HABIT_TO_ROUTINE,
  habit: newHabitType.id,
});

优点

  1. 您不再需要链接操作本身,您只需要按顺序分派它们。
  2. 这保留了最重要的 Redux 准则之一:您的减速器不应有任何副作用(在您的情况下,生成随机 ID)。 reference

缺点

  1. 如果您在多个地方创建新习惯,则必须在每个发送操作的地方生成唯一的 ID。这可能会导致重复代码。对此的解决方案是将用于创建习惯的整个逻辑封装到单个组件中,然后在任何地方重用该组件。