Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: Setting state to an es6 Map

This is more of a general, best-practices question.

I've been playing around here and there with JavaScript Maps and have been trying to find more info on whether or not it's considered an anti-pattern/code smell to set state properties to a Map. The link below is an issue thread in the Redux repo with some comments such as:

"You can use Maps and Sets as state values, but it's not recommended due to serializability concerns."

However this thread is about Redux. What about vanilla React? Anyone have any strong opinions or insight? Sorry if this question is in the wrong place.

https://github.com/reduxjs/redux/issues/1499

like image 853
Jose Avatar asked Dec 04 '18 04:12

Jose


People also ask

Can we use a map as state in React?

Map is one of the most popular and widely used functions when working with React. It has two prominent use cases. It's quite similar to how the filter() works. The first one is to modify the state of the application and the other to render a list of elements efficiently.

How do you set the state of a variable in React?

Syntax: We can use setState() to change the state of the component directly as well as through an arrow function. Example 1: Updating single attribute. We set up our initial state value inside constructor function and create another function updateState() for updating the state.

What is the best way to manage state in React?

Local state is most often managed in React using the useState hook. For example, local state would be needed to show or hide a modal component or to track values for a form component, such as form submission, when the form is disabled and the values of a form's inputs.


1 Answers

If you don't want to use an immutable library you can create a new Map on change:

const [someMap, setSomeMap] = useState(new Map());

And when you need to update it:

setSomeMap(new Map(someMap.set('someKey', 'a new value'));

The same concept applies to Redux:

case 'SomeAction':
  return {
    ...state,
    yourMap: new Map(state.yourMap.set('someKey', 'a new value'))
  }

With regards to serializability it's not a concern for local state. It's good practice to have a Redux store that is serializable though.

Can I put functions, promises, or other non-serializable items in my store state?

It is highly recommended that you only put plain serializable objects, arrays, and primitives into your store. It's technically possible to insert non-serializable items into the store, but doing so can break the ability to persist and rehydrate the contents of a store, as well as interfere with time-travel debugging.

If you are okay with things like persistence and time-travel debugging potentially not working as intended, then you are totally welcome to put non-serializable items into your Redux store. Ultimately, it's your application, and how you implement it is up to you. As with many other things about Redux, just be sure you understand what tradeoffs are involved.

You can see that JSON.stringify unfortunately doesn't work on maps:

console.log(JSON.stringify(
  new Map([['key1', 'value1'], ['key2', 'value2']])
))

If you can get in between the serialization process you can use Array.from:

console.log(JSON.stringify(
  Array.from(new Map([['key1', 'value1'], ['key2', 'value2']]))
))
like image 146
Dominic Avatar answered Sep 25 '22 12:09

Dominic