'React - child component re-renders even if it doesn't rely on the parent state

console.log('Render test') in my Test component runs twice.

The tests state is not used, I just put it there for an example. The Test component doesn't rely on the tests state but it still renders twice. Why?

index.js:

import React from "react";
import ReactDOM from "react-dom";
import AppTest from "./AppTest";

ReactDOM.render(<><AppTest /></>, document.getElementById("container"));

AppTest.js:

import Test from "./Test";
import React, {useState, useEffect} from "react";

function AppTest() {
    const [tests, setTests] = useState([]);

    useEffect(() => {
        setTests(['test1', 'test2']);
    }, []);

    return (
        <>
            <Test />
        </>
    );
}

export default AppTest;

Test.js:

import React, {useEffect} from "react";

function Test() {
    useEffect(() => {
        console.log("Render Test");
    });
    return (
        <h1>Test</h1>
    );
}

export default Test;


Solution 1:[1]

You can use React.memo to prevent rerender unless props change - this has more info - How to stop re render child component when any state changed in react js?

Solution 2:[2]

The component Test is rendered twice because of the behaviour of the AppTest component. The useEffect function in AppTest modify the state of your component with setTests(['test1', 'test2']); so the AppTest component is re-rendered.

As previously said, you can use memoization to avoid re-render Test component:

import React, {useEffect} from "react";
const Test= React.memo(()=> {
    useEffect(() => {
        console.log("Render Test");
    });
    return (
        <h1>Test</h1>
    );
}

export default Test;

Solution 3:[3]

The useEffect runs twice because it's missing a dependency array. Add an empty array to indicate it has no dependencies, and then you will not see multiple log statements:

function Test() {
    useEffect(() => {
        console.log("Render Test");
    }, []);
    // ...
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ross
Solution 2 Brian Thompson
Solution 3 Ross Allen