In general, using a mutable object such as Map
is strongly discouraged.
However, the magic of immer allows immutable objects to be manipulated as though they are mutable.
Specifically, immer supports immutable versions of Map using enableMapSet
In redux-toolkit createReducer
and createSlice
wrap state manipulation with immer's produce
.
Collectively, I think these facts mean code like this should be safe:
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)
},
},
})
However, when I use this in a React component, I get the polite error message 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.
.
Is there a way to safely use Map
without getting this error message?
Define "safely" :)
In theory, you could put anything you want into the Redux store.
In practice, per that FAQ, non-serializable values are likely to cause things like the DevTools to break (which defeats much of the purpose of using Redux in the first place). Use of Map
s and other mutable instances are also likely to cause portions of your UI to not re-render correctly, because React-Redux relies on reference checks to determine if data has changed. So, we specifically tell users that you should never put non-serializable values in the Redux state.
In this particular case, you should be able to use a plain JS object as a lookup table rather than a Map
, and accomplish the same behavior.
As an absolute last resort, you can turn off the serialization checking for certain parts of the state, but we strongly discourage folks from doing that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With