Обновление setState

Рассмотрим следующий пример

import './App.css';
import { useState } from 'react';

export default function App() {
	const [counter, setCounter] = useState(0)

	const increment = () => {
		setCounter(counter + 1);
	};

	return (
		<div className='App'>
			<header className='App-header'>
				<h1>{counter}</h1>
				<button onClick={increment}>increment</button>
			</header>
		</div>
	);
}

Добавим alert чтобы вывести значение переменной counter после вызова setState

const increment = () => {
	setCounter(counter + 1);
	alert(counter)
};

При нажатии на кнопку мы увидим в alert число 0. Хотя на странице счетчик будет равняться 1.

Так происходит потому что переменная counter будет обновлена только когда выполнится код всего компонента. Не только код функции в которой мы запускаем setState, а всего компонента.

Рассмотрим другой пример. Добавим цикл вокруг запуска setState

const increment = () => {
	for (let index = 0; index < 5; index++) {
		setCounter(counter + 1);
	}
};

Мы ожидаем что цикл который будет запущен 5 раз, увеличит значение переменной counter на 5:

1) counter + 1 // 0 + 1 = 1
2) counter + 1 // 1 + 1 = 2
3) counter + 1 // 2 + 1 = 3
4) counter + 1 // 3 + 1 = 4
5) counter + 1 // 4 + 1 = 5

Но счетчик все также продолжит увеличиваться на единицу 1

В React если мы хотим изменять состояние основываясь на последнем текущем актуальном состоянии необходимо передавать в setState стрелочную функцию с параметром, который будет отражать текущее актуальное состояния state для данной переменной.