redux-toolkit createSlice 可以使用 js Map 作为状态吗?

Can a redux-toolkit createSlice use a js Map as state?

一般来说,使用Map这样的可变对象就是strongly discouraged

然而,immer 的魔力允许不可变对象像可变对象一样被操作。

具体来说,immer 使用 enableMapSet

支持 Map 的不可变版本

在 redux-toolkit createReducercreateSlice 中,使用 immer 的 produce 包装状态操作。

总的来说,我认为这些事实意味着这样的代码应该是安全的:

import { createSlice } from '@reduxjs/toolkit'

export const testmapSlice = createSlice({
  name: 'testMap',
  // Using a Map() as redux state
  initialState: new Map(),
  reducers: {
    add: (state, action) => {
      state.set(action.payload.identity, action.payload)
    },
  },
})

但是,当我在 React 组件中使用它时,我收到礼貌的错误消息 A non-serializable value was detected in the state, in the path: `testMap`. Value: Map(1) {"A" => {…}} Take a look at the reducer(s) handling this action type: testMap/add.

有没有办法安全地使用 Map 而不会收到此错误消息?

定义“安全”:)

理论上,您可以任何东西放入 Redux 商店。

实际上,根据该常见问题解答,不可序列化的值可能会导致 DevTools 等问题崩溃(这首先违背了使用 Redux 的大部分目的)。使用 Maps 和其他 mutable 实例也可能导致 UI 的某些部分无法正确重新呈现,因为 React-Redux 依赖于引用检查来确定数据是否具有变了。所以,we specifically tell users that you should never put non-serializable values in the Redux state.

在这种特殊情况下,您应该能够使用普通 JS 对象作为查找 table 而不是 Map,并完成相同的行为。

作为绝对的最后手段,您可以 turn off the serialization checking for certain parts of the state,但我们强烈反对人们这样做。

我认为在状态上使用 Map() 是不安全的,因为 Redux 已经被设计为避免 Reducers 级别的突变,并且当您使用 createSlice() 时,它甚至会在后台处理它.您关于州一级双重安全的想法似乎是您挑起的另一个问题。它可能会导致 UI 不更新。或抛出错误 (Ps:这个纯属类比,我没试过)