gpt4 book ai didi

javascript - 如何使用 redux-toolkit 在另一个切片的 reducer 中访问一个切片的状态

转载 作者:行者123 更新时间:2023-12-05 05:38:57 25 4
gpt4 key购买 nike

我正在尝试使用 getState() 方法访问另一个切片的缩减器中另一个切片的状态,但看起来这是不允许的,因此 Web 应用程序中断。

有谁知道在另一个切片的 reducer 中访问切片状态的推荐方法是什么?我的 Web 应用程序需要这个。

在此先感谢您的帮助

最佳答案

根据Redux docs ,您可以使用 3 种不同的方法:

Many users later want to try to share data between two reducers, butfind that combineReducers does not allow them to do so. There areseveral approaches that can be used:

  1. If a reducer needs to know data from another slice of state, the statetree shape may need to be reorganized so that a single reducer ishandling more of the data.
  2. You may need to write some custom functionsfor handling some of these actions. This may require replacingcombineReducers with your own top-level reducer function. You can alsouse a utility such as reduce-reducers to run combineReducers to handlemost actions, but also run a more specialized reducer for specificactions that cross state slices.
  3. Middleware with async logic such asredux-thunk have access to the entire state through getState(). Anaction creator can retrieve additional data from the state and put itin an action, so that each reducer has enough information to updateits 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 中的 namescounter

如果你不想重组你的状态/切片,那么有选项 2 和 3:

选项 2:使用 reduce-reducer

第三方库 reduce-reducers可以用

在这里,您将定义一个能够访问 counternames 切片的 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com