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

标签 javascript reactjs redux react-redux redux-toolkit

我正在尝试使用 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:

  1. 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.
  2. 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.
  3. 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 中的 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/

相关文章:

javascript - 如何在 testcafe 脚本中添加递归函数检查 xhr 响应?

javascript - 如何将我的幻灯片菜单放回左侧并隐藏在开头?

node.js - React 选择菜单 - 选择多个项目 - 高级

javascript - 使用 Webpack 和 React 在开发环境中模拟外部导入

android - 如何在React Native Expo中的Dropdown选项中动态获取api数据

javascript - react : Dispatch not firing on route change

ASP.NET 如何使用自定义 JavaScript 中的 __doPostBack 和主页面/内容页面

javascript - 在 Firefox 中加载新页面时如何防止未完成的 jquery ajax 事件抛出错误

reactjs - mapStateToProps 根本没有被调用

javascript - React Native Object.freeze 不起作用