如何从 Redux Toolkit 动作内部调用另一个动作

huangapple go评论65阅读模式
英文:

How to call another action from inside a redux toolkit action

问题

I created a scoreSlice slice and created 3 actions: addScore reset generateCard.

当我执行reset操作时,我希望generateCard操作也能工作。我该如何做到这一点?

英文:
const scoreSlice = createSlice({
  name: 'score',
  initialState,
  reducers: {
    addScore: ({ score }, action) => {
      score += action.payload;
    },
    reset: (state) => {
      state.score = 0;
      state.grid = initialState.grid;
      generateCard(2); // How do we do this?
    },
    generateCard: (state, action: PayloadAction<number>) => {

    },
  },
});

I created a scoreSlice slice and created 3 actions: addScore reset generateCard.

When I execute the reset action, I want the generateCard action to also work. How can I do this?

答案1

得分: 1

是的,将多个操作分发是一种常见的做法。

  • 选项 1. 直接将操作分发到事件处理程序。
const handler = () => {
  dispatch(reset());
  dispatch(generateCard(2))
}
  • 选项 2. 创建一个 thunk 来组合相关的操作(需要 redux-thunk 中间件)
const resetAndGenerateCard = (cardNumber) => {
  return (dispatch) => {
    dispatch(reset());
    dispatch(generateCard(cardNumber))
  }
};

const handler = () => dispatch(resetAndGenerateCard(cardNumber))
  • 选项 3. 创建一个新的特殊操作来组合这两种操作类型,并在一个特殊的 reducer 中处理它("特殊" 并不真的特殊,只是需要你考虑一个表示此操作含义的操作类型。action1AndAction2 格式可能不是一个好的操作类型)
const resetAndGenerateCard = (payload) => ({ type: 'RESET_AND_GENERATE_CARD', payload });
// ...
{ 
  resetAndGenerateCardReducer: (state, action) => {
    // 重置
    state.score = 0;
    state.grid = initialState.grid;
    // 生成卡片
    state.cards = [...state.cards, action.payload];
  }
}
// ...

const handler = () => dispatch(resetAndGenerateCard(2))

但有时需要权衡。请查看 Should I dispatch multiple actions in a row from one action creator?

英文:

Yes, it is a common practice to dispatch multiple actions.

  • Option 1. Dispatch actions directly to the event handler.
const handler = () => {
  dispatch(reset());
  dispatch(generateCard(2))
}
  • Option 2. Create a thunk to compose related actions (need redux-thunk middleware)
const resetAndGenerateCard = (cardNumber) => {
  return (dispatch) => {
    dispatch(reset());
    dispatch(generateCard(cardNumber))
  }
};

const handler = () => dispatch(resetAndGenerateCard(cardNumber))
  • Option 3. Create a new special action combine these two action types, and handle it in a special reducer. (The "special" is not really special, it just needs you to think of an action type to represent the meaning of this action. The action1AndAction2 format maybe not good action type)
const resetAndGenerateCard = (payload) => ({ type: 'RESET_AND_GENERATE_CARD', payload });
// ...
{ 
  resetAndGenerateCardReducer: (state, action) => {
    // reset
    state.score = 0;
    state.grid = initialState.grid;
    // generate card 
    state.cards = [...state.cards, action.payload];
  }
}
// ...

const handler = () => dispatch(resetAndGenerateCard(2))

But sometimes there are trade-offs. Take a look at Should I dispatch multiple actions in a row from one action creator?

huangapple
  • 本文由 发表于 2023年6月15日 00:53:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76475901.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定