Skip to main content

Як оновити стан на основі попереднього значення?

1. Проблема при звичайному оновленні

Уяви компонент:

javascript
function Counter() { const [count, setCount] = useState(0); const incrementTwice = () => { setCount(count + 1); setCount(count + 1); }; return <button onClick={incrementTwice}>{count}</button>; }

Ти очікуєш, що при кліку count збільшиться на 2... але насправді - лише на 1!


Чому так відбувається

setCount не оновлює count одразу (він асинхронний). Обидва рядки використовують старе значення count (наприклад, 0). React просто ставить у чергу два однакових оновлення:

"зроби count = 1".

Результат - одне оновлення, значення 1.


2. Правильний спосіб - функціональне оновлення

React дозволяє передати в setState функцію, яка отримує попереднє значення стану:

javascript
setCount(prevCount => prevCount + 1);

Тепер React гарантує, що ти працюєш з актуальним станом, навіть якщо було кілька оновлень поспіль.


Приклад з incrementTwice

javascript
function Counter() { const [count, setCount] = useState(0); const incrementTwice = () => { setCount(prev => prev + 1); setCount(prev => prev + 1); }; return <button onClick={incrementTwice}>{count}</button>; }

Тепер при кліку count збільшиться на 2 тому що кожна функція отримує останнє оновлене значення.


3. Аналогічно працює з об'єктами і масивами

Наприклад:

javascript
const [user, setUser] = useState({ name: "Tim", points: 0 }); function addPoint() { setUser(prev => ({ ...prev, points: prev.points + 1 })); }

Тут prev - це попередній стан user, і ти створюєш новий об'єкт на його основі.


4. Приклад з логом (для наочності)

javascript
function Counter() { const [count, setCount] = useState(0); const handleClick = () => { setCount(prev => { console.log("Попереднє значення:", prev); return prev + 1; }); }; return <button onClick={handleClick}>{count}</button>; }

При кожному кліку ти побачиш у консолі актуальне "попереднє" значення, яке React гарантує навіть при асинхронних апдейтах.


5. Підсумок

Що ти хочеш зробитиЯк писати
Встановити фіксоване значенняsetCount(10)
Збільшити на 1setCount(prev => prev + 1)
Додати елемент у масивsetItems(prev => [...prev, newItem])
Змінити поле об'єктаsetUser(prev => ({ ...prev, name: "Alex" }))

Висновок

setState(value) - просто встановлює новий стан setState(prev => newValue) - оновлює на основі попереднього значення Це безпечний спосіб при:

  • кількох викликах поспіль,
  • асинхронних оновленнях,
  • залежних обчисленнях (наприклад, лічильники, масиви, об'єкти)

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

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

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