A React.memo component that keeps re-rendering is one of the most common performance puzzles — some prop is changing identity every render, and you can't see which. useWhyDidYouUpdate is the debugging hook that tells you: drop it in, and on every render it compares the current props to the previous ones and logs exactly which keys changed, with their old and new values.
Implement useWhyDidYouUpdate(name, props). Keep the previous render's props in a ref, diff them against the current props (by Object.is), and when anything changed, console.log the changes tagged with name. Return the changes object ({ key: { from, to } }), or null when nothing changed — including the first render.
function useWhyDidYouUpdate(name, props) {
// returns { [key]: { from, to } } of changed props, or null
}
function Row(props) {
useWhyDidYouUpdate('Row', props);
// console: Row { onClick: { from: fn, to: fn } } <- a new function each render!
return <div>{props.label}</div>;
}
const changes = useWhyDidYouUpdate('Chart', { data, options });
// changes === { options: { from: {...}, to: {...} } } when `options` is rebuilt
Object.is(prev, next) is false; record { from, to }.from/to as undefined accordingly.null) on the first render or when nothing changed.