我正在尝试使用 getState() 方法访问另一个切片的缩减器中另一个切片的状态,但看起来这是不允许的,因此 Web 应用程序中断。
有谁知道在另一个切片的 reducer 中访问切片状态的推荐方法是什么?我的 Web 应用程序需要这个。
在此先感谢您的帮助
最佳答案
根据Redux docs ,您可以使用 3 种不同的方法:
Many users later want to try to share data between two reducers, but find that combineReducers does not allow them to do so. There are several approaches that can be used:
- If a reducer needs to know data from another slice of state, the state tree shape may need to be reorganized so that a single reducer is handling more of the data.
- You may need to write some custom functions for handling some of these actions. This may require replacing combineReducers with your own top-level reducer function. You can also use a utility such as reduce-reducers to run combineReducers to handle most actions, but also run a more specialized reducer for specific actions that cross state slices.
- Middleware with async logic such as redux-thunk have access to the entire state through getState(). An action creator can retrieve additional data from the state and put it in an action, so that each reducer has enough information to update its own state slice.
示例
假设我们有以下切片:
const namesSlice = createSlice({
name: "Names",
initialState: {
value: [],
name: "Names"
},
reducers: {
...
}
};
const counterSlice = createSlice({
name: "Counter",
initialState: {
value: 0,
name: "Names"
},
reducers: {
...
}
};
const reducer = combineReducers({
counter: counterReducer,
names: namesReducer
});
我们想定义一个操作addName
,它将一个名称(由用户输入)添加到names
数组中,但也会附加当前值counter
在添加名称之前将状态添加到名称上。
选项 1:重构切片
这涉及将 2 个切片合并为一个切片,因此您最终会得到如下内容:
const namesSlice = createSlice({
name: "NamesAndCounter",
initialState: {
value: {
names: [],
counter: 0
},
name: "NamesAndCounter"
},
...
};
这将允许您访问 reducer 中的 names
和 counter
。
如果你不想重组你的状态/切片,那么有选项 2 和 3:
选项 2:使用 reduce-reducer
第三方库 reduce-reducers可以用
在这里,您将定义一个能够访问 counter
和 names
切片的 cross slice reducer:
export const crossSliceReducer = (state, action) => {
if (action.type === "CROSS_SLICE_ACTION") {
const newName = action.payload + state.counter.value;
const namesState = state.names;
state = {
...state,
names: { ...namesState, value: [...state.names.value, newName] }
};
}
return state;
};
// Combine reducers
const reducer = combineReducers({
counter: counterReducer,
names: namesReducer
});
// Add the cross-slice reducer to the root reducer
const rootReducer = reduceReducers(reducer, crossSliceReducer);
// Create store
const store = configureStore({
reducer: rootReducer
});
然后您可以分派(dispatch)以下操作来调用 reducer:
dispatch({ type: "CROSS_SLICE_ACTION", payload: name });
注意:reduce-reducers
库是 no longer being maintained
选项 3:使用 Thunks
使用 thunk(用于调用 API 等异步操作)可以让您了解整个状态。您可以定义一个引用 getState
函数的 thunk,该函数允许您获取全局状态中的任何切片:
export const addWithThunk = createAsyncThunk(
"names/addWithThunk",
async (name, { getState }) => {
return name + getState().counter.value;
}
);
Thunk 在传递给 createSlice()
的参数的 extraReducers
属性中定义:
extraReducers: (builder) => {
builder.addCase(addWithThunk.fulfilled, (state, action) => {
state.value.push(action.payload);
});
}
并且可以像调用普通操作一样调用:
dispatch(addWithThunk(name));
有一个 CodeSandbox demo显示选项 2 和 3。当您使用 Submit
按钮之一添加名称时,它将访问 counter
状态并将计数器的当前值附加到您的名称在将名称添加到 names
状态之前输入。
关于javascript - 如何使用 redux-toolkit 在另一个切片的 reducer 中访问一个切片的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72807148/