Prevent unnecessary re-render with React composition

Prevent unnecessary re-render with React composition

·

2 min read

React encourages people to use special prop children for the container which has unknown children components. For example, Sidebar or Dialog. And avoid component inheritance as much as you can. React doc says it.

Especially, component composition helps us to reduce the unnecessary re-render when the state change. Let's say we have a Container which has Header and BlogContent component, and a button to change color of Header, like this:

Screen Shot 2022-09-24 at 11.41.27.png

Usually, I would organize my component like this:

import { useState } from "react";
import Header from "./Header";
import Blog from "./Blog";

const Container = () => {
    const [color, setColor] = useState("#8dcbff");
return (
    <div>
        <button
            onClick={() => setColor("#ff8789")}
    >    
            change color
        </button>
        <Header color={color} />    
        <Blog />
    </div>
    );
};

export default Container;

When I click the change color button, React will trigger a state change and the whole Container will be re-render, including Header and Blog component. But as we can see the Blog component is not using the color state, so it no need to be re-render for the trigger.

We can re-organize the Container by using children props as the place holder for any component placed in the Container.

Screen Shot 2022-09-24 at 12.06.27.png

The Container would look like this:

import { useState } from "react";
import Header from "./Header";

const Container = ({ children }) => {
    const [color, setColor] = useState("#8dcbff");
    return (
        <div>
            <button
                onClick={() => setColor("#ff8789")}
            >
                change color
            </button>
            <Header color={color} />
            {children}
        </div>
    );
};

export default Container;

Using the <Container /> in App.tsx:

const App = () => (
    <Container>
        <Blog />
    </Container>
)

This will prevent the unnecessary re-render for Blog component.

In short, we should compose our components, make use of `children` prop and passing component which use different state to prevent unnecessary re-render.