Набор инструментов Redux: есть ли у двух частей ссылки на действия друг друга в extraReducers?

Я хотел бы, чтобы два разных фрагмента перекрестно ссылались на действия друг друга следующим образом:

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
        },
    },
});

Проблема в том, что я получаю сообщение об ошибке sliceB undefined при попытке установить extraReducers для sliceA.

Я хотел бы для ясности разделить срезы, но некоторые их действия влияют друг на друга.

Как лучше всего этого добиться?

1 ответ

Вы должны разрешить циклическую зависимость между срезами, выделив создание для одного из действий в вызов createActions, на который оба вызова createSlice могут ссылаться как на extraReducers без циклического определения их.

также обратите внимание на название вашего действия, а затем строка здесь вводит в заблуждение:[sliceA.actions.someReducer]: (state, action) => {

Вы createSlice выполняет как действия, так и редукторы, поэтому используйте имя для действия, которое не подразумевает, что это редуктор.

используйте createAction: https://redux-toolkit.js.org/api/createAction

См. Примечания к циркулярной ссылке здесь: https://redux-toolkit.js.org/usage/usage-guide

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.
        },
    },
});

Другие вопросы по тегам