Набор инструментов 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.
},
},
});