Interview Q&A / System Design

IntermediateQuick answer1 min readUpdated 3 Oct 2026

What is lazy initialisation in useState, and when should you use it?

SHORT ANSWER

Pass a function to useState, as in useState(() => compute()). React runs it only on the first render. Without the function form, the expensive call runs on every render, even though its result is ignored after the first.

Explain it simply

Imagine you pack a full suitcase every morning but only use the first one. Wasteful. useState(compute()) calls compute() on every render because JavaScript evaluates the argument before React sees it; React just ignores the result after the first time.

Passing () => compute() hands React a recipe instead. React cooks it once, on mount.

Example

jsx
function Notes() {
  // runs JSON.parse on every render
  const [a] = useState(JSON.parse(localStorage.getItem("notes") || "[]"));

  // runs only once
  const [b] = useState(() => JSON.parse(localStorage.getItem("notes") || "[]"));
  return <p>{b.length} notes</p>;
}

For cheap values like 0 or "", the plain form is fine.

What to say in the interview

"The argument to useState is evaluated every render unless it is a function. With a lazy initialiser, React calls it only on the first render. I use it for work like parsing localStorage or building a large structure, and pass a plain value for cheap defaults."

Common mistakes

  • Passing the result of the function call, useState(init()), instead of the function itself, useState(init).

#usestate#performance

Related questions

Practise more System Design questions

Test your recall with short answers, then return to the detailed explanations when you need context.

Open System Design quick answers →

Get new questions like this by email

One short email when something new and useful lands. No spam, unsubscribe in one tap.

By subscribing you agree to the Privacy Policy.