如何在createSlice 的reducer 中获取状态值?

Muh*_*ooq 6 javascript typescript reactjs redux redux-toolkit

我在我的反应项目中使用 redux-toolkit。在 createSlice 的 reducer 中,我想在减少最终状态之前使用状态中现有的实体数组并附加新数组。但我无法获得状态值。

这是减速器代码

export const usersSlice = createSlice({
  name: "users",
  initialState: initialUsersState,
  reducers: {
    usersCreated: (state: UsersState, action) => {
      // in real, return count from the server and append the entities on front-end only?
      const { count, entities } = action.payload;
      const existingEntities = state.entities;
      const newEntities = [...existingEntities, ...entities];
      const totalCount = state.totalCount+count;
      return {
        ...state,
        entities: newEntities,
        totalCount: totalCount,
        listLoading: false,
        error: null,
      };
    },
}});

Run Code Online (Sandbox Code Playgroud)

当我调试 state.entites 变量时,它看起来像这样

在此处输入图片说明

有没有办法访问 reducer/extraReducer 中的当前状态值以根据需要重新创建状态?

因为我认为在 reducer 之外直接使用 state 值是一种不好的做法。如果我错了,请指导我。

编辑

@Linda Paiste 创建的代码沙箱工作正常,这意味着我们可以访问 reducer 中的状态变量,但我们无法调试状态变量以深入挖掘该状态变量目前持有的内容,因为 Redux-toolkit 是以自己的方式处理状态......从调试屏幕截图中可以明显看出

在此处输入图片说明

Lin*_*ste 21

总结我和@karlmaxlopez 的评论中的信息:

我将您的代码复制到CodeSandbox 演示中,发现代码确实按预期执行。您可以state.entities像普通数组一样附加到数组,即使在检查或记录时的值state.entities显示为 a 。Proxynull

这是因为 redux-toolkit 使用 Immer 来防止您直接改变状态。在普通的 redux 减速器中,您接收前一个state作为函数参数。作为用户,您有责任不对其进行变异,而是使用非变异方法(例如对象扩展、数组连接等)返回具有更新值的新对象。这就是您在减速器中所做的usersCreated,这完全没问题。

但 redux-toolkit 和 Immer 为如何编写减速器提供了额外的可能性。在Immer reducer中,state函数接收的参数是“草稿”对象。这意味着您可以直接改变草稿对象而不会引起任何问题,因为它只是草稿而不是 true state。

这也意味着,当您尝试检查先前的状态时,它会表现得很奇怪,因为它只是一个草稿,而不是您期望的实际对象。

如果您想要console.log草稿值,可以通过console.log(current(value))使用 immercurrent函数调用来完成此操作,该函数包含在 redux 工具包中。(根据 @markerikson 的评论编辑)。

至于检查每个操作对状态所做的更改,我建议使用Redux DevTools。我能够看到调度了哪些操作、当前状态、进行了哪些更改等。 Redux DevTools 截图

  • 这里的正确答案是,尽管我建议使用 [从 RTK 导出的 Immer `current` API](https://redux-toolkit.js.org/api/other-exports#current) 而不是 `JSON.stringify() `。 (3认同)

小智 7

您可以使用工具包提供的开箱即用的 current 函数来获取当前状态值。

import {
    createSlice,
    current
} from '@reduxjs/toolkit';

export const parserSlice = createSlice({
    name: ReducerKeys.parser,
    initialState,
    reducers: {
        updateData: (state, action) => {
            console.log(action.payload, current(state), 'updating');
        }
    }
});
Run Code Online (Sandbox Code Playgroud)


Den*_*ash 2

您只能引用当前切片状态。

因此,您唯一的选择是传递所需的entities操作payload或将此操作作为 thunk 实现并从其 API 中createAsyncThunk使用。getState()