Noitidart
Noitidart

Reputation: 37238

Container components are bad? Should use store.getState and store.dispatch directly instead?

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

Answers (1)

markerikson
markerikson

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

Related Questions