background

The child component is used in the parent component, but is rerendered whenever any state of the parent component changes. And is a total rerender that includes all child components, whether or not some child components are useful to the value in state.

Class componentshouldComponentUpdate

ShouldComponentUpdate basic concept

ShouldComponentUpdate is a lifecycle function that is called before each render() function and returns a Boolean that determines whether render() should be executed.

ShouldComponentUpdate note points

  1. The first rendering or invocation of a componentforceUpdate()methodsDon’tTrigger callsshouldComponentUpdateMethods;
  2. Of the life cycle functionThe default behaviorIn every timestateTriggers rerendering when changes occur, as this function will if declared itselfcoverThis default behavior is a matter of judgmentstateChanges to determine whether to rerender;

The use of shouldComponentUpdate

class MyComponent extends React.Component {
  state = { count: 0 };

  shouldComponentUpdate(nextProps, nextState) {
    // There is no need to manually update the state value, the component updates automatically
    // this.setState({ ... nextState });

    if (nextState.count <= 3) {
      // If count is greater than 3, the component is not updated
      return true;
    } else {
      return false; }}render() {
    const { count } = this.state;
    return (
      <button onClick={()= > this.setState({ count: count + 1 })}>
        {count}
      </button>); }}Copy the code

Class componentPureComponent

The React.PureComponent is similar to the react.component with shouldComponentUpdate logic built in. It shallow compares the props and state before and after changes, and skips rendering if neither changes.

PureComponent considerations

Note -1. Ensure that all child components are pure components

For example, the following pure component contains a child component that displays the current time:

class Counter extends React.Component {
  state = { count: 0 };

  render() {
    const { count } = this.state;
    return (
      <div style= >
        <div>count: {count}</div>
        <ConstText count={count >2? count : 0} /><button onClick={()= > this.setState({ count: count + 1 })}>Add</button>
      </div>); }}// "pure" components
class ConstText extends React.PureComponent {
  render() {
    const { count } = this.props;
    const d = new Date(a);const time = `${d.getHours()}: ${d.getMinutes()}: ${d.getSeconds()}`;
    console.log('pure rendered', count);

    return (
      <div>
        pure: {count}
        <ConstChild time={time} />
      </div>); }}// Display time subcomponents
class ConstChild extends React.Component {
  render() {
    const { time } = this.props;
    console.log('child rendered', time);
    return <div>{time}</div>}}Copy the code

Page initialization:



After the first two clicks of the button:



At this point, neither the pure component nor its children trigger the update, and the update is triggered at the same time after the third click:

Therefore, components that pass in the same props will always have the same rendering content, which is what Pure components mean, which is somewhat similar to the definition of a Pure function (passing in the same parameters and always getting the same return value).

2. Recognition of changes when the props value is an object

If the value type is complex, such as a reference type (object), it does not go through each property change, even if the actual value of the reference type changes, but because the reference address does not change. Components will still be judged unchanged, resulting in no re-rendering.

The props value is a function that returns a value

<Counter count={() => 3} />
Copy the code

Even if the function actually executes the same value each time, rendering is triggered because the function itself is judged to be a new value each time, rendering the performance optimization ineffective;

Function componentmemo

React. Memo is a higher-order component similar to PureComponent for function components

Function componentuseMemowithuseCallback

If a child uses a variable or function of a reference type of the container component after it is wrapped in React. Memo, these variables and functions will be reassigned when the state inside the container is updated. This will cause the child to be rerendered even if the memo is wrapped. At this point we need to use useMemo and useCallback.

  • useMemoCache variable
  • useCallbackThe cache callback function
import React, { memo, useState, useEffect, useMemo } from 'react'
const Home = (props) = > {
  const [a, setA] = useState(0)
  const [b, setB] = useState(0)
  useEffect(() = > {
    setA(1)}, [])const add = useCallback(() = > {
    console.log('b', b)
  }, [b])

  const name = useMemo(() = > {
    return b + 'xuxi'
  }, [b])
  return <div><A n={a} /><B add={add} name={name} /></div>
}
Copy the code

At this point, component B will not be re-rendered after a is updated.

Function componentuseRef

UseRef returns a mutable ref object whose.current property is initialized as the passed parameter (initialValue). The ref object returned remains constant throughout the life of the component.