Skip to main content

initialValue для useState

1. Базова відмінність

ВаріантЩо робить
useState(initialValue)Одразу обчислює initialValue при кожному рендері
useState(() => initialValue)Обчислює initialValue лише один раз, при першому монтуванні компонента

2. Приклад: без функції

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

Тут expensiveCalculation() виконається при кожному рендері, навіть якщо стан взагалі не змінювався.

Це може бути неефективно, якщо:

  • компонент часто перерисовується,
  • обчислення важке (наприклад, фільтрація великого масиву, запит у localStorage тощо).

3. Приклад: з функцією (лінива ініціалізація)

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

Тепер React:

  • збереже функцію, але викличе її лише один раз, при першому рендері (монтуванні),
  • при наступних рендерах не буде заново обчислювати expensiveCalculation().

Тобто () => expensiveCalculation() - це "лінива" ініціалізація стану.


4. У чому практична користь

Коли використовувати useState(() => ...):

  • Коли обчислення стартового значення дороге:

    javascript
    const [filtered, setFiltered] = useState(() => data.filter(x => x.active));
  • Коли ініціалізація використовує зовнішні ресурси (наприклад, localStorage):

    javascript
    const [theme, setTheme] = useState(() => { return localStorage.getItem("theme") || "light"; });
  • Коли потрібно виконати код один раз, а не при кожному рендері.


Коли можна без функції

Якщо initialValue - просте значення (число, рядок, булеве):

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

Тоді немає сенсу загортати його у функцію - це не дасть виграшу.


Під капотом

React при виклику useState(arg) робить так:

  • Якщо arg - значення, зберігає його напряму;
  • Якщо arg - функція, викликає її (arg()) і зберігає результат.

Тобто:

javascript
useState(5); // -> зберігає 5 useState(() => 5); // -> викликає () => 5 -> зберігає 5

Але другий варіант виконає функцію лише один раз при монтуванні.


Підсумок

ПорівнянняuseState(initialValue)useState(() => initialValue)
Коли обчислюється значенняКожен рендерЛише при першому
Для чого підходитьПрості значенняВажкі обчислення, localStorage, фільтри
ПродуктивністьМоже сповільнюватиБільш оптимально
МеханізмОдразу зберігає значенняСпочатку викликає функцію, потім зберігає результат

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.