通常,使用strongly discouraged这样的可变对象(例如Map
)。
然而,immer的魔力使不可变的对象看起来像是易变的。
具体地说,沉浸式支持使用enableMapSet
的不可变版本的Map。在redux-toolkit createReducer
和createSlice
中,使用沉浸式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
而不会收到此错误消息?
答案 0 :(得分:0)
“安全地”定义:)
从理论上讲,您可以将任何东西放入Redux存储。
在实践中,根据该常见问题解答,不可序列化的值很可能会导致诸如DevTools之类的东西中断(这首先使使用Redux的目的大打折扣)。使用Map
和其他可变实例还可能导致UI的某些部分无法正确重新呈现,因为React-Redux依靠引用检查来确定数据是否已更改。因此,we specifically tell users that you should never put non-serializable values in the Redux state。
在这种特殊情况下,您应该能够将普通的JS对象用作查找表而不是Map
,并实现相同的行为。
作为绝对不得已的方法,您可以turn off the serialization checking for certain parts of the state,但是我们强烈劝阻人们不要这样做。
答案 1 :(得分:0)
我认为在 state 上使用 Map() 是不安全的,因为 Redux 已经被设计为在 Reducers 级别避免突变,并且当您使用 createSlice() 时它甚至会在后台处理它。您对州级双重保障的想法似乎是您引发的另一个问题。它可能会导致 UI 不更新。或抛出错误 (ps:这纯属类比,没试过)