Hint
React.memo does shallow prop comparison. If a parent passes a new object/function reference each render (even with same content), memo will NOT skip. Combine with useMemo/useCallback.
function shallowEqual(a, b) {
const keysA = Object.keys(a), keysB = Object.keys(b);
if (keysA.length !== keysB.length) return false;
return keysA.every(k => a[k] === b[k]);
}
let renderCount = 0;
function memo(Component) {
let prevProps = null;
return (props) => {
if (prevProps && shallowEqual(prevProps, props)) return 'skipped';
prevProps = props;
renderCount++;
return Component(props);
};
}
const Child = ({ x, y }) => 'rendered:' + x + ',' + y;
const MemoChild = memo(Child);
console.log(MemoChild({ x: 1, y: 2 })); // first render
console.log(MemoChild({ x: 1, y: 2 })); // same props
console.log(MemoChild({ x: 1, y: 3 })); // y changed
console.log(renderCount);rendered:1,2 skipped rendered:1,3 2
Explanation: First render: no prevProps, renders. Second: same props (shallowEqual true), skipped. Third: y changed (3≠2), re-renders. Total renders: 2.
Key Insight: React.memo does shallow prop comparison. If a parent passes a new object/function reference each render (even with same content), memo will NOT skip. Combine with useMemo/useCallback.