React is already fast as a view framework, and in act16’s new Fiber architecture, it uses time slicing and high-priority task interrupts to speed up user actions. However, some of the points we missed resulted in unnecessary re-render components, resulting in wasted performance.

How to prevent unnecessary re-render

Using pureComponent

When a component is updated, the pureComponent shouldComponentUpdate should compare props with state. If the component’s props and state are not changed, the Render method should not fire. React automatically provides a shallow comparison:

if (this._compositeType === CompositeTypes.PureClass) { shouldUpdate = ! shallowEqual(prevProps, nextProps) || ! shallowEqual(inst.state, nextState); }return shouldUpdate;
Copy the code

And what does shallowEqual do? The prev and next keys are determined to be the same, and the corresponding values are equal to the references. (Note that references are equal, even if two objects have the same content, they are not equal.)

Although there is a shallow comparison, but more often, due to our writing problems, this layer comparison is invalid.

// Child extends PureComponent
class Parent extends Component {
  render() {
    return (
      <div>
        <Child
          style={{ width: 100 }}
          onClick={()= > {
            // do something
          }}
        />
      </div>); }}Copy the code

This will cause the Child to be updated repeatedly each time because the onClick and style passed in will be different from the last.

Use the same reference for these immutable data

// Child extends PureComponent
class Parent extends Component {
  onChildClick = (a)= > {
    // do something
  };
  childStyle = { width: 100 };
  render() {
    return (
      <div>
        <Child onClick={this.onChildClick} style={this.childStyle} />
      </div>); }}Copy the code

useReact.memo

React.memo is a higher-order component. It is very similar to the React.PureComponent, but it applies to function components, not class components.

If your function component is rendering the same results given the same props, you can improve the performance of the component by wrapping it in a react.Memo call to remember the results of the component’s rendering. This means that in this case React will skip the render component and simply reuse the results of the last render.

By default, it only does shallow comparisons on complex objects (similar to Pure), and if you want to control the comparison process, pass in a custom comparison function as a second argument.

// The default shallow comparison is used if areEqual is not passed
export default React.memo(MyComponent, areEqual);
Copy the code

To return to the same reference above, suppose you now have the following component

const Child = React.memo(MyComponent);
const Parent = (a)= > {
  onChildClick = {
    // do something
  };

  return (
    <div>
      <Child onClick={onChildClick} />
    </div>
  );
};
Copy the code

The onClick passed to the Child every time re-render is a newly produced function, so shallow comparisons fail. Here we can use useCallback to optimize. React hooks useCallback north

const Child = React.memo(MyComponent);
const Parent = (a)= > {
  const onChildClick = useCallback((a)= > {
   // do something} []);return (
    <div>
      <Child onClick={onChildClick} />
    </div>
  );
};
Copy the code

Optimize re-render when using React-redux

ShouldComponentUpdate (); shouldComponentUpdate ()

  • Using theconnectEvery store update, whether related to itself or not, causes the component to re-render. Actually,react-reduxIt allows us to optimize.
/* options { context? : Object, pure? : boolean, areStatesEqual? : Function, areOwnPropsEqual? : Function, areStatePropsEqual? : Function, areMergedPropsEqual? : Function, forwardRef? : boolean, } */
function connect(mapStateToProps? , mapDispatchToProps? , mergeProps? , options?)
Copy the code

We can do comparison optimization with the areStatePropsEqual function.

  • If you usehooks, how to optimize
const result : any = useSelector(selector : Function, equalityFn? : Function)
Copy the code

Optimize with equalityFn.

conclusion

  1. Class components are optimized using PureComponent and function components are optimized using React. Memo
  2. Use the same reference for these immutable data, reducing the use of anonymous functions
  3. React-redux takes notice of our store in advance and performs processing on related stores

reference

Do not abuse the react. memo and PureComponent documents