Reputation: 53
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.
Upvotes: 0
Views: 825
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