React.PureComponent doesn't execute shouldComponentUpdate

I may have missed something, but I have a component like this

export default MyComponent extends React.PureComponent {
    // ...
}

      

When MyComponent is part of another component renderer, MyComponent re-renders every time the parent renders, even when props / state does not change. Thus, it seems that going from React.Component

to React.PureComponent

did not make the component "clean".

I tried adding

console.info(this.shouldComponentUpdate)

      

inside one of the component's methods and it says it's undefined. React.PureComponent

Should n't I add an shouldComponentUpdate

incomplete comparison method?

This has now happened with React 15.5.4 and 15.6.0

+3


source to share


1 answer


A PureComponent doesn't declare shouldComponentUpdate

directly. You cannot visit it with this.shouldComponentUpdate

. There is a variable in the React source code shouldUpdate

:

(simplified source code)

// default is true
var shouldUpdate = true;

if (inst.shouldComponentUpdate) {
  shouldUpdate = inst.shouldComponentUpdate(
    nextProps,
    nextState,
    nextContext,
  );
} else {
  // if it a PureComponent
  if (this._compositeType === ReactCompositeComponentTypes.PureClass) {
    shouldUpdate =
      !shallowEqual(prevProps, nextProps) ||
      !shallowEqual(inst.state, nextState);
  }
}

// ...

if (shouldUpdate) {
  // re-render ..
}

      

Since it's just shallow, the code below returns false and you get re-rendered:

const propA = { foo: 'bar' }
const nextPropA = { foo: 'bar' }

shallowEqual(propA, nextPropA) // false

      

So use objects and arrays carefully. To prove PureComponent works see this example (v15.6): https://codepen.io/CodinCat/pen/eRdzXM?editors=1010

Clicking the button doesn't trigger Foo

render:

enter image description here



Here's another example that PureComponent might not work for you: https://codepen.io/CodinCat/pen/QgKKLg?editors=1010

The only difference is: <Foo someProp={{ foo: 'bar' }} />

Because { foo: 'bar' } !== { foo: 'bar' }

, React will redraw every time. Therefore, it is not good practice to directly create inline objects and arrays in props. A common mistake is writing inline style:

<Foo style={{ color: 'pink' }} />

      

In this case, Foo

it will always re-render, even if it is PureComponent. If you encounter this problem, you can simply retrieve and store the object somewhere, for example:

const someProp = { foo: 'bar' }

<Foo someProp={someProp} />

      

Since someProp === someProp

PureComponent works.

+1


source







All Articles