🔥 🔥 🔥 Do you know all these means to avoid repeated rendering of React components?
Tags: javascript, react, webdev
Published: 2021-10-31 06:11:21

Use React has been three years, in these three years inside also deposited a lot of best practices on React code optimization, today first write a part out and share with you to share. We'll see if the article is popular and then we'll see if we share the later ones.

For each best practice in this post I will provide two examples, one good and one bad, for comparison, and a preview of the `.gif` image.

The article in this piece focuses on optimizing these three situations：

- Parent component update causes child component to render
- Wrong way of writing Props leads to component rendering
- Context updates lead to component rendering

After reading the article if you think it has helped you, please help to click a praise, your praise is the biggest motivation for my creation. **comment kudos can get the source code!!!**

## Parent component update causes child component to render

### Class Example

#### ❎ Error Example Preview

![1.classBad.gif](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a35acb5e75a64b1ca1ee523e1501d063~tplv-k3u1fbpfcp-watermark.image?)

#### ❎ Error Example

```
import React, { Component } from "react";
class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }
  handleClick = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };
  render() {
    const { count } = this.state;
    return (
      <div className="parent">
        <h5>Error Example</h5>
        <p>Parent ComponentCount--{count}</p>
        <button onClick={this.handleClick}>Add</button>
        <Son />
      </div>
    );
  }
}

class Son extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    console.log("Sub-component re-rendered!!!");
    return <div className="son">Sub-components</div>;
  }
}

export { Parent, Son };

```

[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

In this example, a change in the state of the parent component causes the child component to be re-rendered, which is a very normal way to write code, but seriously, it will still cause a waste of performance, after all, the child component is re-rendered! Next, let's see how to solve this problem!

**Note: This example does not mean to eliminate the need to write such code, in fact, optimization is also dependent on the scenario!**

#### ✅ Correct example 1

```
import React, { Component, PureComponent } from "react";
class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }
  handleClick = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };
  render() {
    const { count } = this.state;
    return (
      <div className="parent">
        <h5>Correct example 1</h5>
        <p>Parent ComponentCount--{count}</p>
        <button onClick={this.handleClick}>Add</button>
        <Son />
      </div>
    );
  }
}

class Son extends PureComponent {
  constructor(props) {
    super(props);
  }
  render() {
    console.log("Sub-component re-rendered!!!");
    return <div className="son">Sub-components</div>;
  }
}

export default Parent;

```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

In this example we are mainly borrowing from **PureComponent** to inherit this class, and React will automatically perform **shouldComponentUpdate** for us to perform a shallow comparison optimization update of Props.

**Note: Actually, in all seriousness, components in React are executed by React.createElement(Son), and the resulting component's Props reference is new every time, thus triggering a re-render!**

#### ✅ Correct example 2

```
import React, { Component } from "react";
class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }
  handleClick = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };
  render() {
    const { count } = this.state;
    const { children } = this.props;
    return (
      <div className="parent">
        <h5>Correct example 2</h5>
        <p>Parent Component Count--{count}</p>
        <button onClick={this.handleClick}>Add</button>
        {children}
      </div>
    );
  }
}

export default Parent;

<Parent>
  <Son />
</Parent>
```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

In the optimization of this example, we separate stateful and stateless components and use **children** to pass stateless components in. This will avoid pointless re-rendering! So why would writing it this way avoid re-rendering? Because using 
 **children** directly in the stateful component will avoid using **React.createElement(Son)** to render the child component in the stateful component! This can also be done to optimize!

#### ✅ Correct example 3

```
import React, { Component, memo } from "react";
import { Son } from "./Bad";

const MemoSon = memo(() => <Son></Son>);

class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }
  handleClick = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };
  render() {
    const { count } = this.state;
    return (
      <div className="parent">
        <h5>Correct example 3</h5>
        <p>Parent Component Count--{count}</p>
        <button onClick={this.handleClick}>Add</button>
        <MemoSon />
      </div>
    );
  }
}

export default Parent;

```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

In this example, the idea of optimization is similar to the one mentioned in example 1, we borrowed the **memo** function, which is actually an optimization tool for the **Function component** We are also cheeky here to force the use of a little! The idea of avoiding re-rendering is actually to compare references to Props as well. Decide whether to render or not !!!

#### ✅ Correct example 4

```
import React, { Component, useState, Fragment } from "react";
import { Son } from "./Bad";

const ClickCount = () => {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((old) => old + 1);
  };
  return (
    <Fragment>
      <div>
        <h5>Correct example 4</h5>
        <p>Parent Component Count--{count}</p>
        <button onClick={handleClick}>Add</button>
      </div>
    </Fragment>
  );
};

class Parent extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div className="parent">
        <ClickCount />
        <Son />
      </div>
    );
  }
}

export default Parent;

```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

In this example, our optimization is mainly to remove the state component into one component, so that the state change is separated from the child component. It also avoids the re-rendering of the child components!

**Description: This optimization means seriously speaking or used quite little, depending on the situation use it!**

### Hooks Example

#### Error Example Preview

![1.HooksBad.gif](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0970a11548c54714a7df5718eac2cce6~tplv-k3u1fbpfcp-watermark.image?)

#### ❎ Error Example
```
import { useState } from "react";
const Son = () => {
  console.log("Sub-component re-rendered!!!");
  return <div className="son">Sub-components</div>;
};

const Parent = () => {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((old) => old + 1);
  };
  return (
    <div className="parent">
      <h5>Error Example</h5>
      <p>Parent Component Count--{count}</p>
      <button onClick={handleClick}>Add</button>
      <Son />
    </div>
  );
};

export { Son, Parent };
```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

For Hooks the above is also a very normal way of writing, but compared to Class components, **Function components** have the feature that each time the component is re-rendered, the function is re-executed once. For a Class component, it will only execute **new Class** once, which is actually quite scary when you think about it. For function components, each execution means a new context, a new variable, and a new scope. So we need to pay more attention to the performance optimization of function components.

#### ✅ Correct example 1

```
import { useState } from "react";

const Parent = ({ children }) => {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((old) => old + 1);
  };
  return (
    <div className="parent">
      <h5>Correct example 1</h5>
      <p>Parent Component Count--{count}</p>
      <button onClick={handleClick}>Add</button>
      {children}
    </div>
  );
};

export default Parent;

<Parent>
  <Son />
</Parent

```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

In this example, we use **children** to render child components directly, the principle of which has been explained in the Class component example above.

**Description: Seriously speaking, combining the characteristics of function components this means of optimization is actually a cure for the symptoms, not the root cause!**

#### ✅ Correct example 2

```
import { useState, useMemo } from "react";
import { Son } from "./Bad";
const Parent = () => {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((old) => old + 1);
  };
  return (
    <div className="parent">
      <h5>Correct example 2</h5>
      <p>Parent Component Count--{count}</p>
      <button onClick={handleClick}>Add</button>
      {useMemo(
        () => (
          <Son />
        ),
        []
      )}
    </div>
  );
};

export default Parent;
```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

n this example we use the optimization Hook **useMemo** , we cache the Son component and only when the dependency changes we re-execute the function to complete the re-rendering, otherwise the timing is the same **memoized**, which helps avoid high overhead calculations at each rendering. It also avoids having to redeclare variables, functions, scopes, etc. in the child component each time.

**Note: I think this optimization is absolutely brilliant because useMemo saves the component reference and does not re-execute the function component, thus avoiding the declaration of variables, functions, and scopes within the component. Thus, performance is optimized. Nice!**

#### ✅ Correct example 3

```
import { useState, memo } from "react";
import { Son } from "./Bad";

const SonMemo = memo(Son);

const Parent = () => {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((old) => old + 1);
  };
  return (
    <div className="parent">
      <h5>Correct example 3</h5>
      <p>Parent Component Count--{count}</p>
      <button onClick={handleClick}>Add</button>
      <SonMemo />
    </div>
  );
};

export default Parent;
```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

In this example we use the api **memo**, mainly to compare whether the props reference has changed, thus avoiding the re-rendering of child components!

## Wrong way of writing Props leads to component rendering

### Class Example

#### ❎ Error Example Preview

![2.ClassBad.gif](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1d31e1ec190a42a8bb3b81f5b4df9da9~tplv-k3u1fbpfcp-watermark.image?)

#### ❎ Error Example
```
import React, { Component, PureComponent } from "react";

class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }
  handleClick = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };
  render() {
    const { count } = this.state;
    return (
      <div className="parent">
        <h5>Error Example</h5>
        <p>Parent Component Count--{count}</p>
        <button onClick={this.handleClick}>Add</button>
        <Son componentDetails={{ name: "Sub-components" }} anyMethod={() => {}} />
      </div>
    );
  }
}

class Son extends PureComponent {
  constructor(props) {
    super(props);
  }
  render() {
    const { componentDetails, anyMethod } = this.props;
    console.log("Son -> render -> anyMethod", anyMethod);
    console.log("Son -> render -> componentDetails", componentDetails);
    return <div className="son">{componentDetails?.name}</div>;
  }
}

export { Parent, Son };
```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

The passing of Props in this example is directly wrong way to write it. Because the rendering of the component is mainly rendered by listening to the change of Props and State, that in this example passed props each time is a new object,**because the reference is different, each time the rendering of the parent component will lead to the rendering of the child component. ** So the re-rendering of real numbers caused by this writing should not!

So how should we write it?

#### ✅ Correct example 1

```
import React, { Component, PureComponent } from "react";

class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      componentDetails: { name: "Sub-components" },
    };
  }
  handleClick = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };
  anyMethod = () => {};
  render() {
    const { count, componentDetails } = this.state;
    return (
      <div className="parent">
        <h5>Correct example 1</h5>
        <p>Parent Component Count--{count}</p>
        <button onClick={this.handleClick}>增加</button>
        <Son componentDetails={componentDetails} anyMethod={this.anyMethod} />
      </div>
    );
  }
}

class Son extends PureComponent {
  constructor(props) {
    super(props);
  }
  render() {
    const { componentDetails, anyMethod } = this.props;
    console.log("Son -> render -> anyMethod", anyMethod);
    console.log("Son -> render -> componentDetails", componentDetails);
    return <div className="son">{componentDetails?.name}</div>;
  }
}

export default Parent;

```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

The main correct way to write this example is to pass the variable directly to the child component, because the reference to the variable is the same, so after checking by **PureComponent**, the reference has not changed, thus preventing the child component from rendering!!!

**Note: Strictly speaking, this buggy example is a writing problem that causes re-rendering of subcomponents, so there's no talk of optimization, so let's forbid writing code like the buggy example!**


### Hooks Example

#### ❎ Error Example Preview

![2.HooksBad.gif](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b7bb39ef843e492ab780e9d29430e146~tplv-k3u1fbpfcp-watermark.image?)
#### ❎ Error Example

```
import { useState, useEffect } from "react";
const Son = ({ componentDetails, anyMethod }) => {
  useEffect(() => {
    console.log("Son -> componentDetails", componentDetails);
  }, [componentDetails]);
  useEffect(() => {
    console.log("Son -> anyMethod", anyMethod);
  }, [anyMethod]);
  return <div className="son">{componentDetails.name}</div>;
};

const Parent = () => {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((old) => old + 1);
  };
  return (
    <div className="parent">
      <h5>Error Example</h5>
      <p>Parent Component Count--{count}</p>
      <button onClick={handleClick}>Add</button>
      <Son componentDetails={{ name: "Sub-components" }} anyMethod={() => {}} />
    </div>
  );
};

export { Son, Parent };

```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

In this error example, it is still a problem with the way props are passed! Next see how to correct it!

#### ✅ Correct example 1


```
import { useState, useEffect } from "react";
const Son = ({ componentDetails, anyMethod }) => {
  useEffect(() => {
    console.log("Son -> componentDetails", componentDetails);
  }, [componentDetails]);
  useEffect(() => {
    console.log("Son -> anyMethod", anyMethod);
  }, [anyMethod]);
  return <div className="son">{componentDetails.name}</div>;
};
// This is written for immutable values and can be passed like this
const componentDetails = { name: "Sub-components件" };
const anyMethod = () => {};

const Parent = () => {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((old) => old + 1);
  };
  return (
    <div className="parent">
      <h5>Correct example 1</h5>
      <p>Parent Component Count--{count}</p>
      <button onClick={handleClick}>Add</button>
      <Son componentDetails={componentDetails} anyMethod={anyMethod} />
    </div>
  );
};

export default Parent;

```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

In this example, we simply refer the invariant value **outside the component** to ensure that the reference is unique and will not change as the component is updated. But there is a limitation to this way of writing. It is that it is only suitable for invariant values. But it also effectively avoids duplicate rendering of components.

#### ✅ Correct example 2

```
import { useState, useEffect, useMemo, useCallback } from "react";
const Son = ({ componentDetails, anyMethod }) => {
  useEffect(() => {
    console.log("Son -> componentDetails", componentDetails);
  }, [componentDetails]);
  useEffect(() => {
    console.log("Son -> anyMethod", anyMethod);
  }, [anyMethod]);
  return <div className="son">{componentDetails.name}</div>;
};

const Parent = () => {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((old) => old + 1);
  };

  const anyMethod = useCallback(() => {}, []);

  const [componentDetails] = useMemo(() => {
    const componentDetails = { name: "Sub-components" };
    return [componentDetails];
  }, []);

  return (
    <div className="parent">
      <h5>Correct example 2</h5>
      <p>Parent Component Count--{count}</p>
      <button onClick={handleClick}>Add</button>
      <Son componentDetails={componentDetails} anyMethod={anyMethod} />
    </div>
  );
};

export default Parent;
```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

In this example, two optimization hooks, **useCallback** and  **useMemo** , are used to determine whether to update a value change based on whether the dependency has changed to ensure that the value reference remains unchanged. This is suitable for most writes, but it should not be overused. Otherwise the code will be very confusing.

## Context updates lead to component rendering

### Class Example

#### ❎ Error Example Preview

![3.ClassBad.gif](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b15006e4a38d4327ab68b10e2bd1b270~tplv-k3u1fbpfcp-watermark.image?)

#### ❎ Error Example

```
import React, { Component, createContext } from "react";

const contextValue = createContext(undefined);

class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      handleIncrement:this.handleIncrement
    };
  }
  handleIncrement = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };

  render() {


    return (
      <contextValue.Provider
        value={this.state}
      >
        <div className="parent">
          <h5>Error Example</h5>
          <Son1 />
          <contextValue.Consumer>
            {(conProps) => <Son2 conProps={conProps} />}
          </contextValue.Consumer>
        </div>
      </contextValue.Provider>
    );
  }
}

class Son1 extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    console.log("Subcomponent 1 is re-rendered!");
    return <div className="son">Subassembly 1</div>;
  }
}

class Son2 extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    console.log("Subcomponent 2 is re-rendered!");

    const {
      conProps: { count, handleIncrement },
    } = this.props;
    return (
      <div className="son">
        <p>Subassembly 2--{count}</p>
        <button onClick={handleIncrement}>Add</button>
      </div>
    );
  }
}

export { Parent };
```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

In this example, if you look carefully, when you click the button in child component 2,**t is the state of the parent component that changes** so the problem is that the rendering of the parent component causes the child component to render as well. So how should we avoid duplicate rendering of the child component?

#### ✅ Correct example 1


```
import React, { Component, createContext } from "react";

const contextValue = createContext(undefined);

class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      handleIncrement:this.handleIncrement
    };
  }
  handleIncrement = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };

  render() {
    const { children } = this.props;
    return (
      <contextValue.Provider
        value={this.state}
      >
        <div className="parent">
          <h5>Correct example 1</h5>
          {children}
          <contextValue.Consumer>
            {(conProps) => <Son2 conProps={conProps} />}
          </contextValue.Consumer>
        </div>
      </contextValue.Provider>
    );
  }
}

class Son1 extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    console.log("Subcomponent 1 is re-rendered!");
    return <div className="son">Subassembly 1</div>;
  }
}

class Son2 extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    console.log("Subcomponent 2 is re-rendered!");

    const {
      conProps: { count, handleIncrement },
    } = this.props;
    return (
      <div className="son">
        <p>Subassembly 2--{count}</p>
        <button onClick={handleIncrement}>Add</button>
      </div>
    );
  }
}

export { Parent, Son1 };

<Parent>
 <Son1 />
</Parent>

```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

In this example, we still borrow the mechanism of **children** o render directly, so there is no **Ract.createElement(Son)** api execution in the parent component, and therefore no duplicate rendering!

#### ✅ Correct example 2


```
import React, { Component, createContext, PureComponent } from "react";

const contextValue = createContext(undefined);

class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      handleIncrement:this.handleIncrement
    };
  }
  handleIncrement = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };

  render() {
    return (
      <contextValue.Provider
        value={this.state}
      >
        <div className="parent">
          <h5>Correct example 2</h5>
          <Son1 />
          <contextValue.Consumer>
            {(conProps) => <Son2 conProps={conProps} />}
          </contextValue.Consumer>
        </div>
      </contextValue.Provider>
    );
  }
}

class Son1 extends PureComponent {
  constructor(props) {
    super(props);
  }
  render() {
    console.log("Subcomponent 1 is re-rendered!");
    return <div className="son">Subcomponent 1</div>;
  }
}

class Son2 extends PureComponent {
  constructor(props) {
    super(props);
  }
  render() {
    console.log("Subcomponent 2 is re-rendered!");

    const {
      conProps: { count, handleIncrement },
    } = this.props;
    return (
      <div className="son">
        <p>Subcomponent 2--{count}</p>
        <button onClick={handleIncrement}>Add</button>
      </div>
    );
  }
}

export default Parent;
```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

In this example, we mainly borrow the class **PureComponent** to help us perform the optimization automatically, so it is also possible to avoid duplicate rendering.

**Note: Here you can also force the use of React.memo a bit.**


### Hooks Example

#### ❎ Error Example Preview

![3.HooksBad.gif](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/69380ea1d85e49a9b624e35b4abebc45~tplv-k3u1fbpfcp-watermark.image?)

#### ❎ Error Example

```
import { createContext, useContext } from "react";
import { useCustomReducer } from "../useCustomizeContext";
const CustomizeContext = createContext(undefined);

const Son1 = () => {
  console.log("Subcomponent 1 re-rendered!!!");
  return <div className="son">子组件1</div>;
};
const Son2 = () => {
  const { count, handleIncrement } = useContext(CustomizeContext);
  console.log("Subcomponent 2 re-rendered!!!");
  return (
    <div className="son">
      <p>Subcomponent 2-{count}</p>
      <button onClick={handleIncrement}>Add</button>
    </div>
  );
};

const Parent = () => {
  const value = useCustomReducer({ initValue: 1 });
  return (
    <CustomizeContext.Provider value={value}>
      <div className="parent">
        <h5>Error Example</h5>
        <Son2 />
        <Son1 />
      </div>
    </CustomizeContext.Provider>
  );
};

export { Son1, Parent, Son2 };
```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

In this example, the api's  **createContext，useContext，useReducer** are used to implement a small Redux, and clicking on the button in child component 2 changes the count value, which in turn causes the value to change, so the parent component renders, causing the child component to follow suit.

#### ✅ Correct example 1

```
import React from "react";
import {
  CustomizeProvider,
  useCustomizeContext,
  useCustomReducer,
} from "../useCustomizeContext";

const Son1 = () => {
  console.log("Subcomponent 1 re-rendered!!!");
  return <div className="son">Subcomponent 1</div>;
};
const Son2 = () => {
  const { count, handleIncrement } = useCustomizeContext();
  console.log("Subcomponent 2 re-rendered!!!");
  return (
    <div className="son">
      <p>Subcomponent 2-{count}</p>
      <button onClick={handleIncrement}>Add</button>
    </div>
  );
};

const Parent = ({ children }) => {
  const value = useCustomReducer({ initValue: 1 });
  return (
    <CustomizeProvider value={value}>
      <div className="parent">
        <h5>Correct example 1</h5>
        <Son2 />
        {children}
      </div>
    </CustomizeProvider>
  );
};
export { Son1 };
export default Parent;


<Parent>
 <Son1 />
</Parent>
```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

In this example we are still using **children** to solve the duplicate rendering problem. This still works!

**Description: In fact, you must use the right optimization in your project!**

#### ✅ Correct example 2

```
import React, { memo } from "react";
import {
  CustomizeProvider,
  useCustomizeContext,
  useCustomReducer,
} from "../useCustomizeContext";

const Son1 = () => {
  console.log("Subcomponent 1 re-rendered!!!");
  return <div className="son">Subcomponent 1</div>;
};
const Son2 = () => {
  const { count, handleIncrement } = useCustomizeContext();
  console.log("Subcomponent 2 re-rendered!!!");
  return (
    <div className="son">
      <p>Subcomponent 2-{count}</p>
      <button onClick={handleIncrement}>Add</button>
    </div>
  );
};
// use memo
const MemoSon1 = memo(Son1);
const Parent = () => {
  const value = useCustomReducer({ initValue: 1 });
  return (
    <CustomizeProvider value={value}>
      <div className="parent">
        <h5>Correct example 2</h5>
        <Son2 />
        <MemoSon1 />
      </div>
    </CustomizeProvider>
  );
};

export default Parent;
```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

The api **memo** is also used in this example, and is still the same, comparing whether the reference to the props has changed or not, and deciding whether to update it or not.

#### ✅ Correct Example 3

```
import React, { useMemo } from "react";
import {
  CustomizeProvider,
  useCustomizeContext,
  useCustomReducer,
} from "../useCustomizeContext";

const Son1 = () => {
  console.log("Subcomponent 1 re-rendered!!!");
  return <div className="son">Subcomponent 1</div>;
};
const Son2 = () => {
  const { count, handleIncrement } = useCustomizeContext();
  console.log("Subcomponent 2 re-rendered!!!");
  return (
    <div className="son">
      <p>Subcomponent 2-{count}</p>
      <button onClick={handleIncrement}>Add</button>
    </div>
  );
};

const Parent = () => {
  const value = useCustomReducer({ initValue: 1 });
  return (
    <CustomizeProvider value={value}>
      <div className="parent">
        <h5>Correct Example 3</h5>
        <Son2 />
        {useMemo(
          () => (
            <Son1 />
          ),
          []
        )}
      </div>
    </CustomizeProvider>
  );
};

export default Parent;
```
[✋🏻 Click to view online demo](https://codesandbox.io/s/react-code-best-practices-lzf1o)

In this example we still use the **useMemo** optimization hook to optimize the component.

## 🤙🤙🤙 Summary

The means of optimization in three cases are described in the article of this piece, mainly the use of.

- 🤙useMemo
- 🤙memo
- 🤙children
- 🤙useCallback
- 🤙PureComponent
- 🤙Extracting status components
- 🤙Extraction of constant values

These optimizations can be used in different situations, so you must use the appropriate optimizations if you are in the process of using them in conjunction with your code. 

**If you know other means of optimization can also be left in the comments section Oh!**