'Using ES6 Map with React and/or Redux

I am looking at using the ES6 Map object to do my hashing for me, instead of creating a custom hashing function. However, it seems to me that it doesn't have much support for immutability, which is a key thing for React as well as Redux.

I am used to not using any libraries for immutability, but use just plain destructuring:

const newObj = { ...prevObj, newKey: "value" }

or map/filter with arrays.

However, ES6 Map has methods that directly update the object itself.

What I could think of was to do something like this:

var myMap = new Map()
Var myNewMap = { ...myMap.set() }
this.setState({ myMap:myNewMap })

But I am not sure if that would work.



Solution 1:[1]

All objects in JavaScript are reference types by nature (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#comparing_objects). The only reason that the state object in Redux is immutable is because the library itself doesn't let you directly modify the state object return by getState.

Additionally, a JavaScript object is itself a dictionary, so fetching data from that state object by property name is still O(1) time complexity

Solution 2:[2]

If you just want a type-safe key-value store, you can use the following syntax:

entities: { [id: number]: MyEntity },
...

Solution 3:[3]

I thought about using Map data structure with react +redux recently and decided against it.

Though there is a slight performance benefit, for some use cases, in using the Map, mostly because the compiler knows better what to expect. And you get a size prop for free :)

I think there are more reasons agains this approach:

First of all redux doesn't like non serializable object - faq. it won't work if you want to use SSR or save your data in localStorage.

You can't enjoy many features in the redux toolkit, because they assume / create simple object data structures. for example the the createEntityAdapter - which I personally think is great

You can create a new map in each reducer, but it might get annoying pretty fast, and I'm not sure about the performance.

React doesn't care that much though :)

Solution 4:[4]

I am using an ES6 in React project that uses Redux as well.

use-case #1

Within a component:

I receive the data, then I need to process it, e.g. add some flags and/or additional parameters to each of the elements, then I store it within the component as ES6 Map(not in the component state).

Later when I need to update the data (e.g. new elements were fetched) I'm using Thunk that sets a loading flag in redux, which, later is back to false which triggers the update.

I update my ES6 Map with new data, mutating it, but not creating a new Map. My component gets updated because of the loading flag and re-renders with the new data from internal Map

use-case #2

In Redux state

I have an ES6 Map in my Redux state because I want to share it with multiple components. I keep it immutable like so in a reducer:

const newMap = new Map(oldMap.entries())

but creating new Map on each update is only useful if you don't update it too often, but do often read from it.

In my case I have to use Map in Redux state because ES6 Map is keeping the order of elements while providing O(1) access to them.

So I'd suggest you to figure out parts where it's beneficial to use ES6 Map and where it's fine to just go along with regular Object.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Jared Beach
Solution 3 Alissa
Solution 4 Ivan Satsiuk