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

时间:2020-07-22 15:10:53

标签: redux redux-toolkit immer.js

通常,使用strongly discouraged这样的可变对象(例如Map)。

然而,immer的魔力使不可变的对象看起来像是易变的。

具体地说,沉浸式支持使用enableMapSet

的不可变版本的Map。

在redux-toolkit createReducercreateSlice中,使用沉浸式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而不会收到此错误消息?

2 个答案:

答案 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:这纯属类比,没试过)