PassFront
  1. PassFront
  2. База знаний
  3. Состояние

Как обновить 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 мерджит поля.

Другие вопросы раздела