Reputation: 37238
In react, the way it figures out if it needs to re-render-dom is by testing references of objects/functions.
So on every update all the JS is calculated. Meaning container elements return two brand new objects each time, one for maptDispatchToProps
and one for mapStateToProps
:
const mapStateToProps = (state, ownProps) => {
return {
active: ownProps.filter === state.visibilityFilter
}
}
const mapDispatchToProps = (dispatch, ownProps) => {
return {
onClick: () => {
dispatch(setVisibilityFilter(ownProps.filter))
}
}
}
In above code we see a new object every time containing active
key and then a new object containing a new function to onClick
. The references to these 3 are brand new on each js-cycle. React will compare these references and then it will re-calc the js in the component. But I thought with redux there was no need for testing shouldComponentUpdate
, how can this be when all these 3 references changed? Especiall the onClick
, that will cause react to removeEventListener
then add the onClick
back again with addEventListener
.
Upvotes: 1
Views: 360
Reputation: 67469
You're misunderstanding how "shallow equality" works. Both React's PureRenderMixin
and React Redux's connect
function use "shallow equality" to determine if something has actually changed. That means that the top-level values of two objects are compared to see if each pair of values is ===
equal, rather than comparing if the objects themselves are the same. So, if I have:
var a = {q : 42};
var b = {a : a};
var c = {a : a};
Then B and C are distinctly different objects, but shallow-equal, because for both of them, the "a" field points to the same object.
Also, in the case of React Redux's connect()
function, it primarily checks the return value of mapStateToProps
to see if the wrapped component needs to update.
Upvotes: 2