Skip to main content

initialValue for useState

1. Basic difference

OptionWhat it does
useState(initialValue)Immediately computes initialValue on every render
useState(() => initialValue)Computes initialValue only once, on the component's first mount

2. Example: without a function

javascript
const [value, setValue] = useState(expensiveCalculation());

Here expensiveCalculation() runs on every render, even if the state never changed at all.

This can be inefficient if:

  • the component re-renders often,
  • the computation is heavy (e.g. filtering a large array, a localStorage lookup, etc.).

3. Example: with a function (lazy initialization)

javascript
const [value, setValue] = useState(() => expensiveCalculation());

Now React:

  • stores the function, but calls it only once, on the first render (mount),
  • on subsequent renders it will not recompute expensiveCalculation().

So () => expensiveCalculation() is "lazy" state initialization.


4. What is the practical benefit

When to use useState(() => ...):

  • When computing the starting value is expensive:

    javascript
    const [filtered, setFiltered] = useState(() => data.filter(x => x.active));
  • When initialization uses external resources (e.g. localStorage):

    javascript
    const [theme, setTheme] = useState(() => { return localStorage.getItem("theme") || "light"; });
  • When you need to run code once, not on every render.


When it's fine to skip the function

If initialValue is a simple value (a number, string, boolean):

javascript
const [count, setCount] = useState(0);

Then there's no point wrapping it in a function - it gives no benefit.


Under the hood

When useState(arg) is called, React does the following:

  • If arg is a value, it stores it directly;
  • If arg is a function, it calls it (arg()) and stores the result.

That is:

javascript
useState(5); // -> stores 5 useState(() => 5); // -> calls () => 5 -> stores 5

But the second option runs the function only once, on mount.


Summary

ComparisonuseState(initialValue)useState(() => initialValue)
When the value is computedEvery renderOnly on the first one
What it suitsSimple valuesHeavy computations, localStorage, filters
PerformanceCan slow things downMore optimal
MechanismStores the value directlyCalls the function first, then stores the result

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.