- Writing immutable update logic by hand is really hard to do correctly and hard to read
- Accidental mutations have historically been the number one cause of bugs in Redux apps
Immer eliminates accidental mutations, and makes it _way_ easier to write and read code that does correct immutable updates.
So, we now recommend Immer as the right way to do immutable updates in Redux [0], and Redux Toolkit uses it by default [1].
Agreed that there is absolutely a learning curve aspect here - you need to know why and how to write immutable updates by hand to really appreciate what Immer is doing for you, which is why I've repeatedly highlighted that information in our docs [2].
[0] https://redux.js.org/style-guide/style-guide#use-immer-for-w...
[1] https://redux.js.org/tutorials/fundamentals/part-8-modern-re...
A deep clone would result in unnecessarily copying a bunch of extra objects and arrays that aren't relevant, so that's a waste of cycles. On top of that, the React ecosystem (and React-Redux in particular) relies on reference comparisons to determine if data has changed. If you copy objects that didn't actually get updated, it can cause a lot of components to re-render when they really shouldn't have.
For more details see:
- Dave Ceddia's "Complete Guide to Immutability in React and Redux": https://daveceddia.com/react-redux-immutability-guide/
- The Redux docs page on "Immutable Update Patterns": https://redux.js.org/recipes/structuring-reducers/immutable-...
- The Redux FAQ entry on deep cloning: https://redux.js.org/faq/performance#do-i-have-to-deep-clone...
- The Redux FAQ page on immutability: https://redux.js.org/faq/immutable-data
- Bad: newX = JSON.parse(JSON.stringify(x))
- Slightly Better: newX = lodash.cloneDeep(x)
- Best(using immer): newX = produce(x, draftX => {draftX[1].done = true})
I don't know how JavaScript engines actually assign memory, but I think of object references in JavaScript like pointers in C. If you deep clone you're copying way more than you need, mallocing giant blocks of memory for duplicated data. Libraries like immer(the best) and immutable.js will only copy what you changed, which saves time and memory.