You _can_ do a "deep equality" comparison that recurses through every nested field in both `this.props` and `nextProps`, but that's relatively expensive. The alternative is "shallow equality", which uses pointer/reference equality checks for each field in both objects. However, in order for that to be useful, you need to manage your data in an immutable fashion so that each update results in a new object/array reference, rather than directly modifying the existing objects.
So, you don't _have_ to manage data immutably in React, but doing so enables performance optimizations, and also goes along with React's functional programming influences.
Funny timing. I was actually implementing SCU using deep obj equality for the first time earlier today. I did understand the desire for immutability, but it didn't seem to be a game changer.
React's `setState()` definitely doesn't care if you mutate or not - you can `.push()` right into an existing array in state, and re-set it into state to queue the re-render.
On the Redux side of things, immutability is important for several reasons. First, pure reducer functions are more easily testable. Second, they enable time-travel debugging - without immutability, jumping back and forth in state would cause the state contents to behave unpredictably, breaking time-travel. Third, the React-Redux `connect` function relies on immutability checks against the root of the state tree to see if it _thinks_ anything has changed, and against the return values of your `mapState` functions as well. If you mutate Redux state, your connected components usually won't re-render properly, because they think nothing has changed.
The assumption is that if two objects are different references, then their contents are also different. It's possible that you could have two different objects whose fields point to the exact same contents, but given a typical application setup that's unlikely. So, a simple `a === b` (or if you're looking at all the contents, `first.a === second.a && first.b === second.b && .....`) is just some quick pointer comparisons in the JS engine. So, at the JS level you don't care what the pointer address actually _is_, just whether the two variables point to different things in memory.
More precisely: may be different.
My conclusions were:
- it's as much of a discipline than a tool
- the complexity must be added by the middleware
I had a similar experience with it coming in to a recently-started React Native project at work, having not seen React, React Native, or Redux before. At first I was fairly confused (see: awful terminology, painful example code which everyone seems to take as gospel and which had, in fact, invaded our codebase).
Then I started to get an inkling that I was being tricked. I looked closer and... it's two event dispatchers. One of which it's mostly up to you to implement (the reducer). Plus a really short list of suggestions for how to write the code (mainly: don't screw with state in certain places/ways). That's it.
It's paper thin and dead simple, but somehow most people come away from the tutorials and docs hopelessly confused. I think there's something deeply and perhaps irredeemably wrong with the docs/tutorials and with the way Redux's proselytizers communicate. I can't figure out how else they could manage to confuse so many people about such a simple thing.
Redux is the polar opposite. No amount of documentation will change that. The faster we accept that not every tool is the right one for everyone, the faster we can make better tools that are great and some stuff instead of being mediocre at everything.