如何在 createSlice 的 reducer 中获取状态值?
How can I get the state value in the reducer of createSlice?
我在我的 React 项目中使用 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,
};
},
}});
当我调试state.entites变量时,它看起来像这样
有没有办法访问 reducer/extraReducer 中的当前状态值以根据需要重新创建状态?
因为我假设直接在 reducer 之外使用状态值是一种不好的做法。如果我错了,请指导我。
编辑
@Linda Paiste 创建的 code sandbox 工作正常,这意味着我们可以访问 reducer 中的状态变量,但我们无法调试状态变量以更深入地挖掘状态变量在此刻,因为 Redux-toolkit 正在以自己的方式处理状态......
从调试截图中可以明显看出
您只能引用当前切片状态。
因此,您唯一的选择是将所需的 entities
作为操作的 payload
传递,或者将此操作作为 thunk createAsyncThunk
并使用其 [=19= 中的 getState()
].
总结我自己和@karlmaxlopez 评论中的信息:
我将您的代码复制到 CodeSandbox demo 中,发现代码 确实按预期执行。即使 state.entities
的值在检查时显示为 Proxy
或在记录时显示为 null
,您也可以将其附加到 state.entities
数组,就好像它是一个普通数组一样。
这是因为 redux-toolkit 使用 Immer 来防止您直接改变状态。在普通的 redux reducer 中,您会收到前面的 state
作为函数参数。作为用户,您有责任不改变它,而是通过使用 non-mutating 方法(例如对象传播,数组连接等) return 具有更新值的新对象。这就是您在你的 usersCreated
reducer 中完成了,这完全没问题。
但是 redux-toolkit 和 Immer 为如何编写 reducer 开辟了额外的可能性。在 Immer reducer 中,函数接收的 state
参数是一个“草稿”对象。这意味着您可以直接改变草稿对象而不会引起任何问题,因为它只是草稿而不是真正的 state
.
这也意味着当您尝试检查之前的状态时,它会表现得很奇怪,因为它只是一个草稿,而不是您期望的实际对象。
如果你想 console.log
草稿值,你可以通过使用 immer current
函数调用 console.log(current(value))
来实现,它包含在 redux 工具包中。 (根据@markerikson 的评论编辑)。
就检查每个操作对您的状态所做的更改而言,我建议使用 Redux DevTools。我能够看到发送了哪些操作、当前状态、进行了哪些更改等。
我只是 copying/pasting @Linda Paiste 的 CodeSandbox 解决方案的等价物,因此查找和重用速度更快。
const usersSlice = createSlice({
name: "users",
initialState: {
users: [],
},
reducers: {
userCreated: (state, action) => {
const newUser = action.payload;
const existingUsers = JSON.parse(JSON.stringify(state.users));
const newUsers = [...existingUsers, newUser];
state.users= newUsers;
}
}
});
我在我的 React 项目中使用 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,
};
},
}});
当我调试state.entites变量时,它看起来像这样
有没有办法访问 reducer/extraReducer 中的当前状态值以根据需要重新创建状态?
因为我假设直接在 reducer 之外使用状态值是一种不好的做法。如果我错了,请指导我。
编辑
@Linda Paiste 创建的 code sandbox 工作正常,这意味着我们可以访问 reducer 中的状态变量,但我们无法调试状态变量以更深入地挖掘状态变量在此刻,因为 Redux-toolkit 正在以自己的方式处理状态...... 从调试截图中可以明显看出
您只能引用当前切片状态。
因此,您唯一的选择是将所需的 entities
作为操作的 payload
传递,或者将此操作作为 thunk createAsyncThunk
并使用其 [=19= 中的 getState()
].
总结我自己和@karlmaxlopez 评论中的信息:
我将您的代码复制到 CodeSandbox demo 中,发现代码 确实按预期执行。即使 state.entities
的值在检查时显示为 Proxy
或在记录时显示为 null
,您也可以将其附加到 state.entities
数组,就好像它是一个普通数组一样。
这是因为 redux-toolkit 使用 Immer 来防止您直接改变状态。在普通的 redux reducer 中,您会收到前面的 state
作为函数参数。作为用户,您有责任不改变它,而是通过使用 non-mutating 方法(例如对象传播,数组连接等) return 具有更新值的新对象。这就是您在你的 usersCreated
reducer 中完成了,这完全没问题。
但是 redux-toolkit 和 Immer 为如何编写 reducer 开辟了额外的可能性。在 Immer reducer 中,函数接收的 state
参数是一个“草稿”对象。这意味着您可以直接改变草稿对象而不会引起任何问题,因为它只是草稿而不是真正的 state
.
这也意味着当您尝试检查之前的状态时,它会表现得很奇怪,因为它只是一个草稿,而不是您期望的实际对象。
如果你想 console.log
草稿值,你可以通过使用 immer current
函数调用 console.log(current(value))
来实现,它包含在 redux 工具包中。 (根据@markerikson 的评论编辑)。
就检查每个操作对您的状态所做的更改而言,我建议使用 Redux DevTools。我能够看到发送了哪些操作、当前状态、进行了哪些更改等。
我只是 copying/pasting @Linda Paiste 的 CodeSandbox 解决方案的等价物,因此查找和重用速度更快。
const usersSlice = createSlice({
name: "users",
initialState: {
users: [],
},
reducers: {
userCreated: (state, action) => {
const newUser = action.payload;
const existingUsers = JSON.parse(JSON.stringify(state.users));
const newUsers = [...existingUsers, newUser];
state.users= newUsers;
}
}
});