Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the need of Immutable states for redux

My states are of type Immutable.js in my redux store and I only change the state in my reducers. Would it not make more sense to skip using immutable and have a parser that checks my app on command and warns if I change my store outside the reducer functions? Or is there a good reason as to why this isn't done?

like image 400
Baz Avatar asked Feb 06 '23 02:02

Baz


2 Answers

You can mutate your state in your reducers if you feel like it. Redux does not mandate that you don't mutate your state but it advises against it.

React-Redux, which isn't Redux, is designed with the assumption that state never gets mutated. This allows it to do very fast checks to find out if something changed anywhere in the state hierarchy.

Redux itself will fire an event each time an action is processed, whether it modifies (by mutating or by replacing) the state or not. It never checks state except for undefined. It doesn't care what you do with it.

Immutable state has many benefits but the main one used in Redux is that it's fast to check for modifications. Your "parser", for instance, would need to visit every property and item of every object and array in your entire state each time it runs for it to make a meaningful determination. If React-Redux did the same thing then it would be horribly slow and no one would use it.

So, thousands of developers are constraining themselves to immutablity because it has real advantages beyond academics.

like image 190
DDS Avatar answered Feb 16 '23 14:02

DDS


I think your idea of some type of middleware that could check for inadvertent state mutations is a really cool idea, actually. I'm not sure how feasible/performant it would be (it may even exist already and I just haven't heard of it). But, for those not using some type of library such as Immutable.js or seamless-immutable, I can see how that would be useful.

I just want to clarify that Immutable.js is enforcing that you are not mutating your state, and it's just a consequence of this is that it becomes impossible to change your state from outside of your reducers. There is an important difference between the general programming concept of immutability and the Redux-specific concept of only using reducers to change your state. Immutable.js enforces the former and thereby logically also enforces the latter.

However, the fact that Immutable.js ensures you can't mutate state accidentally is not the only reason for using the library for your Redux store:

  • Performance: Immutable.js has performance optimizations that allow it to enforce immutability while actually sharing the same underlying objects in memory under the hood. This means you aren't performing deep copies of large amounts of data just to change a single item in an array, for example. This can mean a significantly smaller memory footprint in situations where your store has large amounts of data and/or many changes in state.
  • Helper Methods: While you can use various techniques to avoid mutating state, Immutable.js has a really nice API for doing so. For example, if you've ever tried to change something that is deeply nested in arrays and or objects, you'll notice that it is extremely painful to do so with native JS. Immutable.js makes it simple to drill down as deep as you want and change something and chain a bunch of these together.

    return state
      .updateIn(['todos', '5', 'attachment'], attachment => attachment.set('name', 'foo'))
      .set('isProcessing', true)
      .updateIn(['other', 'nested', 'stuff'], stuff => stuff.set('bar', 'baz'));

That being said, it's definitely optional. You've got alternatives like the aforementioned seamless-immutable, lodash-fp, and just doing it manually like so:

return Object.assign({}, state, { name: 'new name' });

For comparison, the Immutable.js alternative would just be:

return state.set('name', 'new name');
like image 37
Rob Wise Avatar answered Feb 16 '23 14:02

Rob Wise