If you don't want to use an immutable library you can create a new Map on change (this is a shallow copy of the map, like spreading an object):
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']]))
))