Focus on

Once the parent is rendered, all the children are rendered, even though nothing has changed for that child. In this case, rendering of the child component becomes redundant.

1. Failure cases

For example 🌰 :


class Child extends Component {
    render() {
        console.log('Child Render! ');
        return (
            <div>
                hello Child!
            </div>
        );
    }
}

class Father extends Component {
    state = {
        count: 1
    }

    render() {
        console.log('Father Render! ');
        return( <div> <div>count: {this.state.count}</div> <button onClick={() => this.setState((state) => ({count: state.count + 1}))}>up 1</button> <Child/> </div> ); }}export default Father;
Copy the code

When the button is clicked and the parent component’s state value is changed, the parent component is naturally rerendered, but the child component does not use the parent component’s state value and ends up rerendered as well!

A waste of resources!

2. Try to solve it

Change the shouldComponentUpdate lifecycle to the Child component.

Because there is no props received from the parent component and no state itself, return false.

If shouldComponentUpdate returns false, the render of this component is not triggered!

class Child extends Component {
    shouldComponentUpdate(nextProps, nextState, nextContext) {
        return false;
    }

    render() {
        console.log('Child Render! ');
        return( <div> hello Child! </div> ); }}Copy the code

So we can customize this shouldComponentUpdate lifecycle to control whether the component is rendered or not.

But every time it’s a hassle, PureComponent is born!

So PureComponent solves the problem of unnecessary rendering of child components!

3. How to use PureComponent

class Demo extends PureComponent{
    ...
}
Copy the code
class Demo extends React.PureComponent{
    ...
}
Copy the code

According to the above example 🌰 :

class Child extends PureComponent {
    render() {
        console.log('Child Render! ');
        return (
            <div>
                hello Child!
            </div>
        );
    }
}

class Father extends Component {
    state = {
        count: 1
    }

    render() {
        console.log('Father Render! ');
        return( <div> <div>count: {this.state.count}</div> <button onClick={() => this.setState((state) => ({count: state.count + 1}))}>up 1</button> <Child/> </div> ); }}export default Father;
Copy the code

When the button is clicked, only the parent component is rendered, and the child component is not!

4. Memo – PureComponent in the function component

PureComponent can only be used for class because function components don’t have a shouldComponentUpdate lifecycle!

But function components are also rendered as the parent component is rendered.

The memo was born!

The example above 🌰 :

const Child = () => {
    console.log('Child Render! ')
    return <div>hello child</div>
}

const MemoChild = memo(Child);

class Father extends Component {
    state = {
        count: 1
    }

    render() {
        console.log('Father Render! ');
        return( <div> <div>count: {this.state.count}</div> <button onClick={() => this.setState((state) => ({count: state.count + 1}))}>up 1</button> <MemoChild/> </div> ); }}Copy the code

5. Features of PureComponent and Memo

1. The light contrast

The comparison between their props and state is shallow

Shallow contrast: objects compare their memory address, as long as the memory address is consistent, do not re-render, conversely, object memory address is inconsistent, render!

So when faced with modifying object values, it is best to create a new object to reassign, so that can play the role of rendering!

2. The memo uses useState/useContext

Memo does not apply to useState/useContext in function components.

This means that the context is updated, and the function component will be re-rendered despite the memo being used.

3. The memo in the “shouldComponentUpdate”

First of all, the memo doesn’t have a shouldComponentUpdate lifecycle, it just has a similar function.

The Memo function can pass two arguments, one for our component and one for a method like shouldComponentUpdate to determine whether or not to render.

memo(ChildComponent,()=>{... })Copy the code

However, it’s worth noting that this method is the opposite of shouldComponentUpdate: if true, do not re-render, if false, do re-render.