dragon25
dragon25

Reputation: 53

Why is child component re-rendering if only prop has useCallback?

Child component only is supposed to re-render if its prop (numberModifier) is modified. numberModifier is using useCallback with no dependencies. Thus, it never changes.

In order to test this, I modify the value of “online” (inside Application) which happens to be the prop of Parent so both Application and Parent are re-rendered when “online” is modified.

That makes sense.

However, Child is also re-rendered. I don’t understand why this is happening. It’s only prop (numberModifier) is not modified.

Why is Child re-rendering when I modify the value of online (Application)?

If that’s the correct behaviour, what’s the point of using useCallback?

function Application() {
 const [online, setOnline] = useState(true);

  return (
    <div>
    <button onClick={()=>setOnline(!online)}>Change Flag</button>
    <Parent online={online}/>
    </div>
  );
}
function Parent({online}) {
  const [number, setNumber] = useState(1);
  const numberModifier = useCallback(()=> {
    setNumber(69)
  },[])

  return (
    <>
    <p>Online is {online.toString()}</p>
    <p>Number is {number}</p>
    <Child numberModifier={numberModifier} />
    </>
  );
}
function Child({ numberModifier }) {
    return (
        <button onClick={numberModifier}>modify</button>
    );
}

This is a screenshot taken from profiler. That shows that Child is re-rendered because its parent was re-rendered. Note: Child is the green bar.

enter image description here

Upvotes: 0

Views: 825

Answers (1)

dante
dante

Reputation: 1121

Ok, so when if there's somethig changes in states in parent component, all the child components are re-rendered except you wrap your Child component using React.memo(Child).

const [online, setOnline] = useState(true);

  return (
    <div>
    <button onClick={()=>setOnline(!online)}>Change Flag</button>
    <Parent online={online}/>
    </div>
  );

when online states has been changed, all the child components re rendered, in this case your <Parent online={online}/>

because your Parent get props online, whole nested component inside your Parent will be re-rendered no matter you wrap numberModifier with useCallback.

If you want to prevent your Child Component re-render, wrap your Child Component with React.memo()

Upvotes: 1

Related Questions