Состояние компонента


Что делает метод setState?

setState() планирует обновление объекта состояния компонента. Когда состояние изменяется, компонент отвечает переотрисовкой.


Какая разница между state и props?

props (сокращение от «properties») и state - оба обычные объекты JavaScript. Хотя каждый из них содержат информацию, которая влияет на результат отрисовки компонента, между ними имеется важное отличие: props передается компоненту (аналогично параметрам функции), тогда как state управляется внутри компонента (подобно переменным, объявленным внутри функции).

Вот некоторые полезные ресурсы для более подробного изучения того, когда необходимо использовать props или state:


Почему setState мне дает неправильное значение?

В React оба this.props и this.state представляют отображаемые значения, то есть то, что в данный момент отображается на экране.

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

Пример кода, который будет вести себя не так, как ожидалось:


Код
    
  incrementCount() {
    // Обратите внимание: он будет вести себя не так, как ожидается
    this.setState({count: this.state.count + 1});
  }

  handleSomething() {
    // Пусть `this.state.count` начинается с 0.
    this.incrementCount();
    this.incrementCount();
    this.incrementCount();
    // Когда React перересует компонент, `this.state.count` будет равен 1, но вы ожидали 3.

    // Это произошло потому, что функция `incrementCount()` читает значение из `this.state.count`,
    // но React не обновляет `this.state.count` до тех пор, пока компонент не будет перерисован.
    // Таким образом `incrementCount()` читает `this.state.count` как 0 каждый раз и устанавливает его в 1.

    // Исправление этой проблемы будет описано ниже!
  }

Читайте далее, чтобы узнать как исправить эту проблему.


Как мне обновлять состояние новыми значениями, которые зависят от текущего состояния?

Передайте функцию вместо объекта в метод setState, чтобы гарантировать, что вызов всегда использует самую обновленную версию состояния (см. ниже).


В чем отличие между передачей объекта и функции в метод setState?

Передача функции обновления позволяет получить доступ к текущему значению состояния компонента внутри неё. Поскольку вызовы setState группируются, это позволяет вам выстраивать цепочку обновлений и обеспечивать их последовательное выполнение, избегая конфликтов:


Код
    
  incrementCount() {
    this.setState((prevState) => {
      // Важно: считывайте `prevState` вместо `this.state` во время обновления.
      return {count: prevState.count + 1}
    });
  }

  handleSomething() {
    // Предположим `this.state.count` начинается с 0.
    this.incrementCount();
    this.incrementCount();
    this.incrementCount();

    // Если вы сейчас считаете значение `this.state.count`,
    // оно по прежнему будет равно 0.
    // Но когда React переотрисует компонент, оно будет равно 3.
  }

Читайте больше о setState.

Когда setState асинхронен?

На данный момент setState асинхронен внутри обработчиков событий.

Это гарантирует, например, что если оба Parent и Child вызывают setState во время события click, Child не перерисовывается дважды. Вместо этого React «сбрасывает» обновления состояния в конце события браузера. Это приводит к значительным улучшениям производительности в более крупных приложениях.

Это всё детали реализации, не полагайтесь на них! В будущих версиях React в большинстве случаев будет группировать обновления в пакеты по умолчанию.


Почему React не обновляет this.state синхронно?

Как объяснялось в предыдущем разделе, React намеренно «ждет» до тех пор, пока все компоненты не вызовут setState() в своих обработчиках событий, перед началом переотрисовки. Это повышает производительность, избегая ненужных переотрисовок.

Тем не менее, у вас все равно может оставаться вопрос, почему React просто не обновляет this.state немедленно без переотрисовки.

На это есть две главные причины:

  • Это может поломать консистентность между props и state, вызывая проблемы, которые очень тяжело отладить.
  • Это сделало бы невозможным реализацию наших некоторых новых функций.

Данный комментарий на GitHub дает глубокое описание специфических примеров.


Следует ли мне использовать специальные библиотеки для управления состоянием, вроде Redux или MobX?

Возможно.

Рекомендуется сначала познакомиться с React, прежде чем добавлять дополнительные библиотеки. Вы можете создавать довольно сложные приложения, используя только React.