Performance (memo/useMemo)
5 questions foundWhat does React.memo do and how does it help performance?
Beginner React.memo wraps a component and tells React to skip re rendering it if its props have not actually changed since the last render. This is useful for components that render often but whose output usually stays the same, saving unnecessary rendering work.
const ProductCard = React.memo(function ProductCard({ name, price }) {
console.log('Rendering', name);
return <div>{name}: ${price}</div>;
});
Real-world example A product grid with hundreds of cards avoids re rendering every single card whenever an unrelated part of the page updates, since each card is wrapped in React.memo and only re renders when its own specific data changes.
Common follow-ups: Does React.memo compare props deeply or just by reference?;When could using React.memo actually make performance worse instead of better?
Hooks;useReducer & Complex State Logic
What is the useCallback hook and how is it different from useMemo?
Intermediate useCallback remembers a function itself between renders, so the same function reference is reused instead of creating a brand new one every time. useMemo remembers the result of a calculation instead of a function. Both help avoid unnecessary work, but useCallback is specifically for functions, often used together with React.memo to prevent child components from re rendering unnecessarily.
function ParentComponent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log('Button clicked');
}, []);
return <ChildButton onClick={handleClick} />;
}
const ChildButton = React.memo(({ onClick }) => <button onClick={onClick}>Click</button>);
Real-world example A parent component passes the same stable function reference to a memoized child button using useCallback, preventing the child from re rendering every time the parent updates for an unrelated reason.
Common follow-ups: What happens if you use React.memo on a child component but forget to use useCallback on the function passed to it?;How do you decide when a function actually needs to be wrapped in useCallback?
Performance (memo/useMemo);Hooks
How would you use the React Profiler to find which components are causing performance problems?
Advanced The React DevTools Profiler tab lets you record how long each component takes to render during an interaction, showing a visual chart of exactly which components re rendered and how much time each one took. This helps you identify the real bottleneck instead of guessing which part of the app is actually slow.
// No code changes needed, this is a browser DevTools feature
// 1. Open React DevTools
// 2. Click the Profiler tab
// 3. Click record, interact with your app, then stop recording
// 4. Review which components took the longest to render
Real-world example A team notices their app feels sluggish while typing in a search box, and using the Profiler, discovers that a large, unrelated sidebar was re rendering on every keystroke, which they fix by wrapping it in React.memo.
Common follow-ups: What does a very tall bar in the Profiler's flame chart usually indicate?;How do you compare two separate profiling recordings to check if a fix actually helped?
React DevTools & Debugging;Custom Hooks
Why should you avoid overusing useMemo and React.memo throughout an entire app?
Intermediate Every use of useMemo or React.memo has a small cost of its own, since React still needs to check whether the dependencies changed. Adding them everywhere, especially to simple, fast components, can add unnecessary complexity and sometimes even slow things down slightly, without providing any real benefit. They work best when applied specifically to components or calculations that are genuinely expensive or re render very often.
// Unnecessary, this component is already extremely fast to render
const SimpleText = React.memo(({ text }) => <p>{text}</p>);
// Worthwhile, this involves genuinely expensive filtering work
const filtered = useMemo(() => expensiveFilter(hugeList), [hugeList]);
Real-world example A team removes React.memo from several tiny, simple components after realizing it added unnecessary complexity without any measurable performance benefit, keeping it only on the few components that actually needed it.
Common follow-ups: How do you measure whether a specific optimization actually made a real difference?;What is a good rule of thumb for deciding when a component is worth memoizing?
React DevTools & Debugging;Design Patterns in React
What is a simple real world example of when useMemo actually helps a React app?
Beginner Imagine a component that sorts a very large list of items every time it renders. If the list itself has not changed, sorting it again on every render wastes time. Wrapping that sort operation in useMemo means React only redoes the sorting when the actual list changes, saving unnecessary work on unrelated re renders.
function SortedList({ items }) {
const sortedItems = useMemo(
() => [...items].sort((a, b) => a.name.localeCompare(b.name)),
[items]
);
return <ul>{sortedItems.map((item) => <li key={item.id}>{item.name}</li>)}</ul>;
}
Real-world example A contact list app avoids re sorting thousands of contacts every time an unrelated part of the screen updates, since the sorting work is wrapped in useMemo and only runs again when the actual contact list changes.
Common follow-ups: What happens if you forget to include items in the dependency array of this useMemo?;Would this same optimization matter if the list only had five items instead of thousands?
Custom Hooks;Conditional Rendering & Lists (Keys)