Redux工具箱:是否有两个切片在extraReducers中互相引用了自己的动作?

时间:2020-04-10 10:52:05

标签: redux-toolkit

我希望两个不同的片段可以像这样相互引用彼此的动作:

const sliceA = createSlice({
    name: "sliceA",
    initialState: null,
    reducers: {
        someReducer: (state, action) => {
            // do something
        },
    },
    extraReducers: {
        [sliceB.actions.anotherReducer]: (state, action) => {
            // do something
        },
    },
});

const sliceB = createSlice({
    name: "sliceB",
    initialState: null,
    reducers: {
        anotherReducer: (state, action) => {
            // do something else
        },
    },
    extraReducers: {
        [sliceA.actions.someReducer]: (state, action) => {
            // do something else
        },
    },
});

问题是我在尝试为sliceA设置extraReducers时收到未定义sliceB的错误。

为了清晰起见,我想将切片分开,但是它们的某些动作相互影响。

什么是实现此目标的好方法?

1 个答案:

答案 0 :(得分:2)

您必须通过将操作之一的创建分解为createActions调用来解决切片之间的循环依赖关系,两个createSlice调用都可以将它们作为额外的还原剂引用,而其定义不是循环的。

还请注意您的动作命名,然后此处的行会引起误解: [sliceA.actions.someReducer]: (state, action) => {

您的createSlice同时在做动作还原器,因此请为该动作使用一个名称,并不表示它是还原器。

使用createAction:https://redux-toolkit.js.org/api/createAction

在此处查看循环参考注释:https://redux-toolkit.js.org/usage/usage-guide#exporting-and-using-slices

const actionOnAThatAffectsB = createAction('B_ACTION_NAME', function prepare(text) {
  // this function is an optional parameter to createAction.
  // only use it if you want to add to the eventual payload.
  return {
    payload: {
      text,
      id: nanoid(),
      createdAt: new Date().toISOString()
    }
  }
})

const sliceB = createSlice({
    name: "sliceB",
    initialState: null,
    reducers: {
        actionOnBThatAffectsA: (state, action) => {
            // do main stuff on A
        },
    },
    extraReducers: {
        [sliceA.actions.someAction]: (state, action) => {
            // do other stuff.
        },
    },
});

const sliceA = createSlice({
    name: "sliceA",
    initialState: null,
    reducers: {},
    extraReducers: {
        [sliceB.actions.actionOnBThatAffectsA]: (state, action) => {
            // do extra stuff on A
        },
        [actionOnAThatAffectsB]: (state, action) => {
            // you can't create the *action* here with createSlice's default creation through the reducers{} parameter — since that leads to a circular reference during creation.
            // You *are* creating the *reducer* itself here, though.
        },
    },
});