React recursively re-renders child components, but there is a nuance
February 01, 2023
Wait… React recursively re-renders child components on state update?
Yes - A Visual Guide to React Rendering. However, re-render ≠ DOM update. React uses reconciliation to update only the minimum required part of the DOM.
So, why doesn’t React re-render the children prop?
React re-renders recursively, and when it comes across the element that preserves its referential identity from the previous render, it can stop the recursion.
The props passed to the component preserve their identity between re-renders when this component’s state updates. That’s why structuring components this way can act as an alternative to memoization.
But why passed props preserve identity between renders?
In the example above, the children
prop comes from the parent of the Resizer
. And when we trigger a state update of Resizer
, the Resizer
re-renders, but its parent does not. Therefore <Hello />
element is not getting recreated and keeps its referential identity between re-renders of the Resizer
. Note that if we update the state of the parent, everything will re-render.
This optimization applies to any props, not just children
.
// When the state of "Resizer" updates
//"children" and "handle" won't re-render
function Resizer({ children, handle }) {
let [x, updateX] = useState(0)
return (
<div style={{ width: x }}>
{children}
<span>{handle}</span>
</div>
)
}
How do I use it in practice?
This feature goes hand in hand with the state colocation technique. It allows for the natural optimization of a React app by structuring components in a way that isolates the state with the parts of UI this state is updating - Optimizing React performance without refs and memo.
Don’t use this guide as a reason for over-analyzing re-renders prematurely, as it is counter-productive.
Coding challenge
The LongList
component gets re-rendered on every mouse move causing performance problems. Could you improve the app’s performance by applying the technique from this article? CodeSandbox.
Send the link with your solution as the reply to this tweet
Related articles
- Before you memo by Dan Abramov
- One simple trick to optimize React re-renders by Kent C. Dodds
- A (Mostly) Complete Guide to React Rendering Behavior by Mark Erikson