Now, everything works fine when we remove a person—List re-renders because the people array changes. But what happens when we click the count button? 🤔
The Unexpected Re-render!
When we click on the count button, the removePerson function is re-created on each render. Because the function reference changes, it’s considered a new value by React. So, even though the people array hasn’t changed, the removePerson function prop is treated as "changed," causing the List component to re-render unnecessarily.
The Memoization Breakdown
In the List component, we used memo, which only prevents re-renders if the props change. However, the function passed as a prop (removePerson) is created from scratch every time the App component re-renders (because of the setCount state change). This means that React sees the removePerson function as "changed" every time the App re-renders.
Here’s what happens:
Expected behavior: List should not re-render if only the count changes and the people array stays the same.
Actual behavior: Listdoes re-render because the removePerson function is recreated every time the App component re-renders.
DevTools Insight
We can see this in the React DevTools Profiler. Even though the people array hasn’t changed, we can clearly see that the removePerson function is treated as a prop change, triggering a re-render of the List component.
Here’s the breakdown:
The removePerson function is created from scratch on every render, and React treats it as a new prop.
This causes List to re-render, even though the people prop hasn’t changed.
Why Is This Happening?
memo is working fine for checking props, but it doesn’t handle functions that are recreated on each render.
React sees the function as a new value every time, causing unnecessary re-renders.
The Solution: useCallback
Next, we’ll introduce the useCallback hook, which will help us preserve the function reference across renders, preventing unnecessary re-renders in this scenario.
With useCallback, we can ensure that removePerson only gets recreated when the dependencies (like setPeople) change, not every time the component re-renders.
Stay tuned for the fix! 🔧
TL;DR:
Memoization works for props, but it doesn't prevent re-renders caused by function references changing.
Using useCallback will help us preserve the function reference and avoid unnecessary re-renders when only other state (like count) changes.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
MIND GRENADE!!! 💣
Imagine we need to add a
removePersonmethod to remove a person from a list. So, let’s start with the basic setup inApp.jsx:App.jsx
In this code, we’re removing a person by filtering the
peoplearray, and passing theremovePersonfunction down to theListcomponent.List.jsx (Memoized Component)
We use
memohere to memoize theListcomponent, so it only re-renders if thepeopleorremovePersonprops change.Person.jsx (Displaying Each Person)
What’s the Problem?
Now, everything works fine when we remove a person—
Listre-renders because thepeoplearray changes. But what happens when we click the count button? 🤔The Unexpected Re-render!
When we click on the count button, the
removePersonfunction is re-created on each render. Because the function reference changes, it’s considered a new value by React. So, even though thepeoplearray hasn’t changed, theremovePersonfunction prop is treated as "changed," causing theListcomponent to re-render unnecessarily.The Memoization Breakdown
In the
Listcomponent, we usedmemo, which only prevents re-renders if the props change. However, the function passed as a prop (removePerson) is created from scratch every time theAppcomponent re-renders (because of thesetCountstate change). This means that React sees theremovePersonfunction as "changed" every time theAppre-renders.Here’s what happens:
Listshould not re-render if only thecountchanges and thepeoplearray stays the same.Listdoes re-render because theremovePersonfunction is recreated every time theAppcomponent re-renders.DevTools Insight
We can see this in the React DevTools Profiler. Even though the
peoplearray hasn’t changed, we can clearly see that theremovePersonfunction is treated as a prop change, triggering a re-render of theListcomponent.Here’s the breakdown:
removePersonfunction is created from scratch on every render, and React treats it as a new prop.Listto re-render, even though thepeopleprop hasn’t changed.Why Is This Happening?
memois working fine for checking props, but it doesn’t handle functions that are recreated on each render.The Solution:
useCallbackNext, we’ll introduce the
useCallbackhook, which will help us preserve the function reference across renders, preventing unnecessary re-renders in this scenario.With
useCallback, we can ensure thatremovePersononly gets recreated when the dependencies (likesetPeople) change, not every time the component re-renders.Stay tuned for the fix! 🔧
TL;DR:
useCallbackwill help us preserve the function reference and avoid unnecessary re-renders when only other state (likecount) changes.