There are two questions:
- Generally, when does a
PureComponent
instance update?
- Is the
PureComponent
component instance updating in this example?
Question #1: PureComponent
does a shallow comparison of props in shouldComponentUpdate
. What this means is described well in the answer to this question. To summarize, a shallow comparison checks for equality of reference rather than equality of value. So, if lastProps.myObj
and nextProps.myObj
are both references to the same object, a shallow comparison evaluates to true
even if lastProps.myObj.foo
and nextProps.myObj.foo
are not equal.
Question #2: If you have mutated state.foo
, so that it's the same object with a changed value, then a shallow comparison will return a false negative. The complicating factor here is that your example uses Redux. You say that a Redux reducer has changed state.foo
. One of the first rules of Redux reducers is that they don't mutate state or props. They return a new state. When state is an object, they make a copy of the object and apply the change to the copy. If you are honoring the reducer contract and updating the state without mutating it, then you have changed the reference. In that case, the PureComponent.prototype.shouldComponentUpdate
should return true
.
// create an object
var foo = {bar: 'bar'};
// make a copy of the object
var bar = Object.assign({}, foo);
// both objects look the same, i.e. have the same property with an equal value
foo.bar === bar.bar // -> true
// but they are not the same object so the shallow comparison evaluates to false
foo === bar // -> false
So if the PureComponent
instance is not updating when state.foo
has changed, I would review the reducer that changes foo
and make sure the update is not a mutation.