When should I use React.memo?
Use React.memo on components that render often with identical props and perform non-trivial computation or render large subtrees. Don't wrap trivial components where memoization overhead exceeds re-render cost.
A React app feels laggy when state changes in parent components trigger cascading re-renders across hundreds of unmodified child components. Using React DevTools Profiler to isolate the trigger, moving state down to the components that actually consume it, and memoizing context values with useMemo restores immediate responsiveness.
If you pass an object literal like 'value={{ user, theme }}' directly into a Context Provider, a new object reference is created on every render, forcing every useContext consumer to re-render.
Putting local form input state in the top-level page component forces the header, sidebar, navigation, and graphs to re-evaluate on every single keystroke.
Rendering 1,000 DOM elements simultaneously overloads browser layout calculation. Virtualization renders only the 20 visible rows currently on screen.
import { createContext, useContext, useState, useMemo, ReactNode } from 'react';
const UserContext = createContext<any>(null);
export function UserProvider({ children }: { children: ReactNode }) {
const [user, setUser] = useState(null);
const [theme, setTheme] = useState('dark');
// useMemo prevents new object creation unless user or theme explicitly changes
const contextValue = useMemo(() => ({
user,
setUser,
theme,
setTheme
}), [user, theme]);
return (
<UserContext.Provider value={contextValue}>
{children}
</UserContext.Provider>
);
}| Lag Symptom | Underlying Culprit | Optimization Pattern |
|---|---|---|
| Keystroke lag in forms | State lifted to parent page | Move state down into an isolated FormField component |
| Entire app re-renders on theme change | Unmemoized context object | Wrap provider value with useMemo() |
| Table scroll stutter (500+ rows) | Too many active DOM nodes | Virtualize with @tanstack/react-virtual |
| Child re-renders despite identical props | Inline arrow function prop | Wrap callback in useCallback() and child in React.memo() |
Push state down to the lowest possible node in the component hierarchy.
Split high-frequency changing state from static configuration context.
Implement list windowing on data tables containing more than 50 rows.
Production Verification
A dashboard updating thousands of live router telemetry metrics simultaneously without dropping below 60fps.
Use React.memo on components that render often with identical props and perform non-trivial computation or render large subtrees. Don't wrap trivial components where memoization overhead exceeds re-render cost.
No. useMemo carries memory overhead to store dependency arrays. It is beneficial when calculating expensive operations (like sorting large datasets) or stabilizing object references passed to child memoized components.
Open React DevTools in Chrome, go to the 'Profiler' tab, check 'Record why each component rendered', click record, perform the laggy action, and inspect the flamegraph.
If this error is blocking your release build or production pipeline, Syed Alijah Muhammad can diagnose and deploy a clean fix. Send the repository access, error trace, and platform details.