Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 857
Dusty Phillips Avatar asked Nov 15 '22 07:11

Dusty Phillips


1 Answers

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 Maps 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.

like image 85
markerikson Avatar answered Dec 19 '22 16:12

markerikson