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

Dus*_*ips 15 redux immer.js redux-toolkit

一般来说,强烈建议不要Map使用可变对象,例如.

\n

然而,沉浸式的魔力允许对不可变的对象进行操作,就好像它们是可变的一样。

\n

具体来说,immer 使用enableMapSet支持Map 的不可变版本

\n

在 redux-toolkit 中createReducercreateSlice使用 immer\'s 包装状态操作produce

\n

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

\n
import { createSlice } from \'@reduxjs/toolkit\'\n\nexport const testmapSlice = createSlice({\n  name: \'testMap\',\n  // Using a Map() as redux state\n  initialState: new Map(),\n  reducers: {\n    add: (state, action) => {\n      state.set(action.payload.identity, action.payload)\n    },\n  },\n})\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

有没有办法安全使用Map而不出现此错误消息?

\n

mar*_*son 8

定义“安全”:)

理论上,你可以任何你想要的东西放入 Redux 存储中。

实际上,根据该常见问题解答,不可序列化的值可能会导致 DevTools 之类的东西崩溃(这首先违背了使用 Redux 的大部分目的)。使用Maps 和其他可变实例也可能导致 UI 的某些部分无法正确重新渲染,因为 React-Redux 依赖于引用检查来确定数据是否已更改。因此,我们特别告诉用户,永远不要将不可序列化的值放入 Redux 状态

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

作为绝对的最后手段,您可以关闭对状态某些部分的序列化检查,但我们强烈建议人们不要这样做。

  • 我特别好奇 immer 是否会改变什么。如果我使用 immutableJS,我可以将初始值设置为 Map 并且知道它是不可变的并且 redux 很高兴。但是由于 immer 是 redux-toolkit 的默认设置,我想知道是否有办法告诉 redux,“这是由 immer 冻结的”在初始状态。对于我的用例,映射的插入顺序迭代是可取的,但键的数量很少,所以我可能会使用数组代替。 (3认同)