React useState
state updater functions are guaranteed to be stable references, so Child2
is only rerendering because the parent component Parent
is rerendering due to the state update. If you want to hint to React that it can likely bail on rerendering a child component then use the memo Higher Order Component.
const Child2 = ({ setValue }) => {
....
};
export default memo(Child2);
Demo
Demonstrates 2 "instances" of Child 2, one decorated with the memo
HOC and the other not. All children use an useEffect
to log when they are rendered. Note that all initially render, but only child 1 and 2 (w/o memo) continually are rerendered.

Sandbox code:
import { memo, useEffect, useState } from "react";
import "./styles.css";
const Child1 = ({ value }) => {
useEffect(() => console.log("Child 1 rendered"));
return <div>Child1: {value}</div>;
};
const Child2 = ({ id, setValue }) => {
useEffect(() => console.log(`${id} rendered`));
return (
<div>
{id}: <input type="text" onChange={(e) => setValue(e.target.value)} />
</div>
);
};
const Child2wMemo = memo(Child2);
const Parent = () => {
const [value, setValue] = useState("");
return (
<>
<Child1 value={value} />
<Child2 id="Child 2" setValue={setValue} />
<Child2wMemo id="Child 2 with Memo" setValue={setValue} />
</>
);
};
export default function App() {
return (
<div className="App">
<Parent />
</div>
);
}
