HomeGuidesReactReact Component Lifecycle — Mount, Update, Unmount & Re-render Rules
⚛️ React

React Component Lifecycle and Rendering Behaviour

Understanding when and why React renders is critical for performance. Here's what senior interviews cover.

Examifyr·2026·6 min read

When does a component re-render?

A component re-renders when its state changes, its props change, or its parent re-renders.

function Parent() {
    const [count, setCount] = useState(0);

    return (
        <div>
            <button onClick={() => setCount(c => c + 1)}>
                Count: {count}
            </button>
            <Child />  {/* re-renders every time Parent re-renders */}
        </div>
    );
}

function Child() {
    console.log('Child renders');
    return <p>I'm a child</p>;
}

// Even though Child has no props, it re-renders when Parent does.
// Fix: wrap in React.memo
const Child = React.memo(function Child() {
    return <p>I'm a child</p>;
});

Lifecycle with useEffect

useEffect maps to the class component lifecycle: componentDidMount, componentDidUpdate, componentWillUnmount.

// componentDidMount equivalent: runs once after mount
useEffect(() => {
    initAnalytics();
    return () => cleanupAnalytics();  // componentWillUnmount
}, []);

// componentDidUpdate equivalent: runs when deps change
useEffect(() => {
    fetchUser(userId);
}, [userId]);

// Runs after every render (both mount and update)
useEffect(() => {
    document.title = title;
});

Lifting state up

When two components need to share state, move the state to their closest common ancestor.

// WRONG: each component has its own state — they're out of sync
function TemperatureInput({ unit }) {
    const [value, setValue] = useState('');
    // celsius and fahrenheit inputs can't sync
}

// RIGHT: lift state to the parent
function Calculator() {
    const [celsius, setCelsius] = useState('');

    const toCelsius = (f) => (f - 32) * 5 / 9;
    const toFahrenheit = (c) => c * 9 / 5 + 32;

    return (
        <>
            <Input unit="C" value={celsius}
                onChange={setCelsius} />
            <Input unit="F" value={toFahrenheit(celsius)}
                onChange={c => setCelsius(toCelsius(c))} />
        </>
    );
}

React.memo and preventing unnecessary renders

React.memo wraps a component to skip re-renders if props haven't changed.

// Without memo: re-renders every time parent renders
const ListItem = ({ item, onDelete }) => (
    <li>
        {item.text}
        <button onClick={() => onDelete(item.id)}>Delete</button>
    </li>
);

// With memo: only re-renders if item or onDelete reference changes
const ListItem = React.memo(({ item, onDelete }) => (
    <li>
        {item.text}
        <button onClick={() => onDelete(item.id)}>Delete</button>
    </li>
));

// IMPORTANT: pair with useCallback to stabilise onDelete reference
const onDelete = useCallback((id) => {
    setItems(items => items.filter(i => i.id !== id));
}, []);
Note: React.memo + useCallback together prevent unnecessary child re-renders. Either alone is usually not enough.

Exam tip

"What triggers a re-render in React?" is a fundamental interview question. Answer: state change, prop change, or parent re-render. React.memo opts a component out of the third case — but only if props are stable (no new object/function references).

🎯

Think you're ready? Prove it.

Take the free React readiness test. Get a score, topic breakdown, and your exact weak areas.

Take the free React test →

Free · No sign-up · Instant results

← Previous
React Forms — Controlled Components, onChange & Form Submission
← All React guides