Lifecycle questions test whether you understand when React runs your code, not just what it runs. Even in a hooks-first world, interviewers ask about the mounting, updating and unmounting phases because they map directly to useEffect, and because older code still uses class lifecycle methods. The questions below cover both worlds and, crucially, the translation between them.
How to answer lifecycle questions
Frame everything around three phases — mounting, updating, unmounting — and one modern tool: useEffect. Class components had a named method per moment; hooks collapse them into effects that run after render, keyed by dependencies. When asked about any class method, give the phase it belongs to and its hooks equivalent. That mapping is the answer most lifecycle questions are really after.
Q1. What are the phases of a component's lifecycle?
Three phases: mounting, when the component is created and inserted into the DOM; updating, when it re-renders because its props or state changed; and unmounting, when it is removed from the DOM. Each phase is a moment where you may need to run code — set up data on mount, react to changes on update, clean up on unmount.
Thinking in phases is what makes effects intuitive: an effect is "run this after the DOM reflects the latest render, and clean it up when appropriate." The phases are the when; the effect is the how.
Interview note: Follow-up: "does re-render always mean the DOM changed?" No — React re-runs the component and diffs; the DOM updates only where output actually differs. Rendering and committing to the DOM are distinct steps.
Q2. What are the main class lifecycle methods?
On mount: constructor, render, then componentDidMount (fetch data, set up subscriptions). On update: render, then componentDidUpdate(prevProps, prevState) (react to changes). On unmount: componentWillUnmount (clean up). Plus getDerivedStateFromProps and shouldComponentUpdate for edge cases and optimisation.
class Timer extends React.Component {
componentDidMount() { this.id = setInterval(this.tick, 1000); }
componentWillUnmount() { clearInterval(this.id); } // cleanup
render() { return <span>{this.state.seconds}</span>; }
}
You should read this fluently even if you never write it, because legacy components and third-party code still use it.
Interview note: Trap: "what runs between render and the DOM update?"
getSnapshotBeforeUpdate— a rarely-used method to capture DOM info (like scroll position) just before the commit. Knowing it exists signals depth.
Q3. How does componentDidMount map to hooks?
componentDidMount becomes useEffect(() => {...}, []) — an effect with an empty dependency array runs once after the component mounts and the DOM is painted. Use it for one-time setup: initial data fetch, subscriptions, timers.
useEffect(() => {
fetchData(); // runs once after mount, like componentDidMount
}, []);
Interview note: Follow-up: "is the effect truly equivalent to didMount?" Nearly — the effect runs after paint, whereas
componentDidMountruns after the DOM update but before the browser paints. For visual measurements before paint,useLayoutEffectis the closer match.
Q4. How do componentDidUpdate and componentWillUnmount map to hooks?
componentDidUpdate is covered by an effect with dependencies: it runs after mount and again whenever a listed value changes. componentWillUnmount is the cleanup function you return from the effect — React runs it before unmount, and also before re-running the effect.
useEffect(() => {
const sub = source.subscribe(id); // like didMount / didUpdate
return () => sub.unsubscribe(); // like componentWillUnmount
}, [id]); // re-subscribe when id changes
Interview note: Trap: "why does cleanup run before every re-run, not only on unmount?" So the previous effect's resources are released before the next effect sets up new ones — preventing duplicate subscriptions when the dependency changes.
Q5. What is the cleanup function, and what breaks without it?
The cleanup function returned by an effect undoes the effect's setup — clearing intervals, removing event listeners, unsubscribing, aborting fetches. Without it you get memory leaks, duplicate listeners, timers that keep firing after unmount, and "cannot update state on an unmounted component" style bugs.
useEffect(() => {
const onResize = () => setWidth(window.innerWidth);
window.addEventListener("resize", onResize);
return () => window.removeEventListener("resize", onResize); // essential
}, []);
Interview note: Follow-up: "what leaks if you forget it here?" Every mount adds another
resizelistener that is never removed, so handlers pile up and fire multiple times — a classic leak.
Q6. Why does React run effects twice in development?
React Strict Mode intentionally mounts, unmounts and remounts components in development, running each effect's setup, then cleanup, then setup again. It surfaces effects that leak (missing cleanup) or are not idempotent. It only happens in development; production runs the effect once.
The correct reaction is not to suppress it but to make effects resilient: proper cleanup and no assumption that setup runs exactly once. If double-invocation breaks your effect, the effect had a latent bug.
Interview note: Trap: "double-invoke duplicated my API call in dev — is that a bug?" It reveals the effect is not safe to run twice; add cleanup (abort the request) and idempotent logic. In production it fires once, but the fix makes it correct either way.
Q7. What replaces shouldComponentUpdate and PureComponent in hooks?
React.memo wraps a function component to skip re-rendering when props are shallow-equal — the hooks-era equivalent of PureComponent / shouldComponentUpdate. For expensive values and stable references within a component, useMemo and useCallback play a supporting role. These are optimisations to apply after measuring, not by default.
Interview note: Follow-up: "does
React.memodeep-compare props?" No — it does a shallow comparison. Pass a custom comparison function as the second argument if you need different behaviour, but that is rarely worth it.
Q8. What is useLayoutEffect and when do you need it?
useLayoutEffect runs synchronously after the DOM is updated but before the browser paints, unlike useEffect which runs after paint. Use it when you must read layout (measure a DOM node) and change it before the user sees a flicker — for example, measuring then repositioning a tooltip. Otherwise prefer useEffect, which does not block painting.
Interview note: Trap: "your effect causes a visible flicker — which hook?" If you are reading and mutating layout, move it to
useLayoutEffectso the change happens before paint;useEffectruns after paint, causing the flash.
Q9. Where do effects fit for data fetching, and what is the modern alternative?
You can fetch in useEffect — trigger on the relevant dependencies, guard against races and unmount in cleanup — but modern apps prefer a data library (React Query) or the router/framework's data layer, which handle caching, deduplication and races for you. Interviewers like to hear both: you understand the raw effect version and know when to reach for the purpose-built tool. The 2-year experience set covers the raw fetch pattern in more detail.
Interview note: Follow-up: "why is fetching in an effect discouraged now?" It leaves you hand-rolling loading state, caching, dedup and race handling; a data layer solves all of that and removes the effect entirely.
How to prepare
Write the same small feature twice — a subscription or timer as a class with componentDidMount/componentWillUnmount, then as a function component with useEffect and cleanup — and line them up side by side. That comparison cements the mapping every lifecycle question is testing. Then deliberately run it under Strict Mode, watch the double-invoke, and fix it with proper cleanup so the behaviour stops surprising you. Pair this with the components and props foundation and the 2-year experience questions where effects show up as real bugs, refresh the details in the React learning path, and use a mock interview to practise the class-to-hooks mapping out loud.
Frequently Asked Questions
What are the phases of the React component lifecycle?
How does useEffect map to class lifecycle methods?
What is the cleanup function in useEffect for?
Why does React run my effect twice in development?
Are class lifecycle methods still relevant?
Want to Build Your Career in Java Full Stack with AI?
Join CodeBegun and train with working industry engineers — Explore the Java Full Stack program

