Как обновить state в React?
Состояние
Состояние в React обновляется только через специальные функции — сеттер useState, dispatch useReducer или this.setState в классах. Прямое присваивание и мутации React не видит.
Функциональные компоненты: useState
const [count, setCount] = useState(0);
const [user, setUser] = useState({ name: 'Аня', age: 25 });
setCount(1); // прямое значение
setCount((prev) => prev + 1); // функциональное обновление
setUser({ ...user, age: 26 }); // объект — только новая копияПравила:
- Функциональная форма — когда новое значение зависит от старого: несколько
setCount((c) => c + 1)подряд применятся корректно, аsetCount(count + 1)дважды даст +1 (оба видят старый count из замыкания). - Иммутабельность — мутация (
user.age = 26; setUser(user)) не обновит компонент: ссылка та же, Object.is посчитает состояние неизменным. - Асинхронность — после вызова сеттера переменная в текущем коде не меняется; новое значение придёт со следующим рендером. Обновления батчатся: несколько сеттеров в обработчике — один рендер.
useReducer — для сложного состояния
const [state, dispatch] = useReducer(reducer, initial);
dispatch({ type: 'item_added', item });Переходы описаны в чистой функции-редьюсере; компоненты сообщают события.
Классы: this.setState
this.setState({ count: this.state.count + 1 });
this.setState((state) => ({ count: state.count + 1 })); // функциональная формаОтличие от хуков: setState мерджит поля объекта (не заменяет state целиком) и вызывает рендер без сравнения значений.
Коротко для собеседования
Обновлять только сеттером/dispatch: setX(value) или setX((prev) => ...) (функциональная форма — при зависимости от прошлого значения), объекты и массивы — новой копией (spread/map/filter). Обновления асинхронны и батчатся. В классах this.setState мерджит поля.