4.2 React.Component


Данный раздел содержит подробную справку по API для компонента-класса React. Предполагается, что вы знакомы с основными понятиями React, такими как компоненты и свойства, состояние и жизненный цикл. Если нет, сперва ознакомьтесь с ними.



4.2.1 Обзор


React позволяет вам определять компоненты как классы или функции. Компоненты, определенные как классы, в настоящее время предоставляют больше возможностей, которые подробно описаны в этом разделе. Чтобы определить класс компонента React, вам нужно расширить React.Component:


Код
    
  class Hello extends React.Component {
    render() {
      return <h1>Привет, {this.props.name}</h1>;
    }
  }
  

Единственный метод, который вы должны определить в подклассе React.Component, называется render(). Все остальные методы, описанные в этом разделе, являются необязательными.

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


Внимание!

React не принуждает вас использовать синтаксис классов ES6. Если вы предпочитаете избегать его, то можете использовать модуль create-react-class или аналогичную пользовательскую абстракцию. Изучите раздел "React без ES6", чтобы узнать больше.


4.2.1.1 Жизненный цикл компонента

Каждый компонент имеет несколько «методов жизненного цикла», которые вы можете переопределить для запуска кода в определенное время в процессе работы приложения. Вы можете использовать эту диаграмму жизненного цикла как шпаргалку. В приведенном ниже списке часто используемые методы жизненного цикла отмечены жирным шрифтом. Остальные из существуют для относительно редких случаев использования.


4.2.1.1.1 Монтирование

Эти методы вызываются в следующем порядке, когда экземпляр компонента создается и вставляется в DOM:


Внимание!

Эти методы считаются устаревшими, и вам следует избегать их в новом коде:



4.2.1.1.2 Обновление

Обновление может быть вызвано изменениями свойств или состояния. Эти методы вызываются в следующем порядке, когда компонент перерисовывается:


Внимание!

Эти методы считаются устаревшими, и вам следует избегать их в новом коде:



4.2.1.1.3 Демонтирование

Этот метод вызывается, когда компонент удаляется из DOM:


4.2.1.1.4 Обработка ошибок

Эти методы вызывается при возникновении ошибки во время отрисовки, в методе жизненного цикла или в конструкторе любого дочернего компонента.


4.2.1.2 Другие API

Каждый компонент также предоставляет некоторые другие API:


4.2.1.3 Свойства класса


4.2.1.4 Свойства экземпляра



4.2.2 Справка


4.2.2.1 Часто используемые методы жизненного цикла


Методы, описанные в этом разделе, охватывают подавляющее большинство случаев, с которыми вы столкнетесь при создании компонентов React. Для наглядного ознакомления посмотрите эту диаграмму жизненного цикла.


render()


Код
    
  render()
  

Метод render() является необходимым.

При вызове он получает доступ к this.props и this.state. В версиях React меньше 16 данный метод должен возвращать единственный элемент React, может являться либо представлением нативного DOM-компонента, например, <div />, либо другого составного компонента, который вы определили сами.

Вы также можете вернуть значение null или false, чтобы указать, что вы не хотите ничего отрисовывать.

Начиная с 16 версии React методrender() может вернуть один из следующих типов:

  • React-элемент. Обычно создается через JSX и может быть либо представлением нативного DOM-компонента (<div />), либо определяемого пользователем составного компонента (<MyComponent />).
  • Массивы и фрагменты. Позволяют вам вернуть несколько элементов из render. Смотрите документацию по фрагментам для более подробной информации.
  • Порталы. Создаются с помощью ReactDOM.createPortal.
  • Строки и числа. Они отображаются как текстовые узлы в DOM.
  • Boolean и null. Ничего не отрисовывается. (Преимущественно существуют для поддержки return test && <Child /> паттерна, где test является логическим значением.)

Метод render() должен быть чистой функцией, что означает:

  • он не изменяет состояние компонента
  • возвращает один и тот же результат при каждом вызове
  • не взаимодействует напрямую с браузером.

Если вам нужно взаимодействовать с браузером, вместо этого выполните свою работу в componentDidMount() или других методах жизненного цикла. Поддержание render() чистым делает компоненты более легкими для анализа.


Внимание!

render() не будет вызываться, если shouldComponentUpdate() возвращает false.


constructor()


Код
    
  constructor(props)
  

Если вы не инициализируете состояние и не привязываете методы, вам не нужно реализовывать конструктор для вашего компонента React.

Конструктор компонента React вызывается до его монтирования. При реализации конструктора подкласса React.Component вы должны вызвать super(props) перед любым другим оператором. В противном случае this.props не будет определен в конструкторе, что может привести к ошибкам.

Как правило, в React конструкторы используются только для двух целей:

Вы не должны вызывать setState() в constructor(). Вместо этого, если вашему компоненту нужно использовать локальное состояние, присвойте начальное состояние this.state непосредственно в конструкторе:


Код
    
  constructor(props) {
    super(props);
    // Нельзя вызывать this.setState() здесь!
    this.state = { counter: 0 };
    this.handleClick = this.handleClick.bind(this);
  }
  

Конструктор - это единственное место, где вы должны назначить this.state напрямую. Во всех других методах вам нужно использовать this.setState().

Избегайте каких-либо побочных эффектов или подписок в конструкторе. Для этих случаев используйте метод componentDidMount().


Внимание!

Избегайте копирования props в state! Это распространенная ошибка:


Код
    
  constructor(props) {
   super(props);
   // Не делайте этого!
   this.state = { color: props.color };
  }
  

Проблема заключается в том, что это копиравание не нужно (вместо этого можно использовать this.props.color напрямую). Также это создает ошибки (обновления свойства color не будут отражаться в состоянии).

Используйте этот шаблон, только если вы намеренно хотите игнорировать обновления props. В этом случае имеет смысл переименовать свойство, чтобы оно называлось initialColor или defaultColor. Затем вы можете принудительно заставить компонент «сбросить» свое внутреннее состояние, изменяя значение этого ключа при необходимости.

Изучите данный раздел о том, как избежать использования производного состояния. В нем вы узнаете как поступить, если вы считаете, что вам нужно определенное состояние, зависящее от props.



componentDidMount()


Код
    
  componentDidMount()
  

componentDidMount() вызывается сразу после монтирования компонента. Инициализация, требующая доступа к узлам DOM, должна находиться здесь. Если вам нужно загружать данные с удаленного источника, это хорошее место для инициирования сетевого запроса.

Этот метод является хорошим местом для добавления подписок. Если вы это сделаете, не забудьте удалить подписки в componentWillUnmount().

Вы можете немедленно вызвать setState() в componentDidMount(). Это вызовет дополнительную отрисовку, но она произойдет до того, как браузер обновит экран. Это гарантирует, что даже если render() будет вызываться дважды, пользователь не увидит промежуточное состояние. Используйте этот шаблон с осторожностью, поскольку он часто вызывает проблемы с производительностью. В большинстве случаев вы должны иметь возможность назначить начальное состояние в constructor(). Однако это может быть необходимо для случаев, таких как модальные окна и всплывающие подсказки, когда вам нужно измерить узел DOM перед отрисовкой чего-либо, что зависит от размера или положения этого узла.


componentDidUpdate()


Код
    
  componentDidUpdate(prevProps, prevState, snapshot)
  

componentDidUpdate() вызывается сразу после обновления. Этот метод не вызывается для первоначальной отрисовки.

Используйте его как возможность работать с DOM сразу после того, как компонент был обновлён. Это также хорошее место для выполнения сетевых запросов, при условии что вы сравниваете текущие свойства с предыдущими свойствами (например, сетевой запрос может не понадобиться, если свойства не изменились).


Код
    
  componentDidUpdate(prevProps) {
    // Типичный вариант использования (не забудьте сравнить props):
    if (this.props.userID !== prevProps.userID) {
      this.fetchData(this.props.userID);
    }
  }
  

Вы можете немедленно вызвать setState() в componentDidUpdate(), но учтите, что вызов должен быть заключен в условие, как в примере выше, иначе вы вызовете бесконечный цикл. Это также вызвало бы дополнительную повторную отрисовку, которая, хоть и незаметно для пользователя, могла бы повлиять на производительность компонента. Если вы пытаетесь «отразить» свойства в состояние, рассмотрите возможность использования props напрямую. Узнайте больше о том, почему копирование props в state вызывает ошибки.

Если ваш компонент реализует метод ЖЦ getSnapshotBeforeUpdate() (что редко встречается), возвращаемое им значение будет передано в качестве третьего параметра «снимка» в componentDidUpdate(). В противном случае этот параметр будет undefined.


Замечание.

componentDidUpdate() не будет вызываться, если shouldComponentUpdate() возвращает false.


componentWillUnmount()


Код
    
  componentWillUnmount()
  

сomponentWillUnmount() вызывается непосредственно перед демонтированием и уничтожением компонента. Выполняйте любую необходимую очистку в этом методе, такую как сброс таймеров, завершение сетевых запросов или удаление любых подписок, которые были созданы в componentDidMount().

Вы не должны вызывать setState() в componentWillUnmount(), потому что компонент никогда не будет перерисован. Однажды демонтированный экземпляр компонента, не может быть монтирован повторно.


4.2.2.2 Редко используемые методы жизненного цикла


Методы в данном разделе соответствуют более редким случаям использования. Они могут удобны время от времени, но большинству ваших компонентов, вероятно, не нужен ни один из них. Большинство методов, представленных ниже, можно увидеть на этой диаграмме жизненного цикла, если в верхней части окна установить флажок «Показать реже используемые функции».


shouldComponentUpdate()


Код
    
  shouldComponentUpdate(nextProps, nextState)
  

Используйте shouldComponentUpdate(), чтобы позволить React быть осведомлённым, не влияет ли на результат отрисовки компонента текущее изменение состояния или свойств. Поведение по умолчанию заключается в повторной отрисовке при каждом изменении состояния, и в подавляющем большинстве случаев вам следует полагаться на поведение по умолчанию.

shouldComponentUpdate() вызывается перед отрисовкой при получении новых свойств или изменении состояния. По умолчанию используется значение true. Этот метод не вызывается для начальной отрисовки или при использовании forceUpdate().

Данный метод существует только для оптимизации производительности. Не полагайтесь на него, чтобы «предотвратить» отрисовку, так как это может привести к ошибкам. Подумайте об использовании встроенного PureComponent вместо написания shouldComponentUpdate() вручную. PureComponent выполняет поверхностное сравнение props и state, а также и снижает вероятность того, что вы пропустите необходимое обновление.

Если вы уверены, что хотите написать его вручную, вы можете сравнить this.props с nextProps, this.state с nextState и вернуть false, чтобы сообщить React, что обновление можно пропустить. Обратите внимание, что возвращение false не предотвращает повторную отрисовку дочерних компонентов при изменении их состояния.

Мы не рекомендуем делать глубокие проверки равенства или использовать JSON.stringify() в shouldComponentUpdate(). Это очень неэффективно и будет наносить ущерб производительности.

В настоящее время, если shouldComponentUpdate() возвращает false, то методы UNSAFE_componentWillUpdate(), render() и componentDidUpdate() не сработают. Но обратите внимание, что в будущем React может рассматривать результат вызова shouldComponentUpdate() как подсказку, а не строгую директиву, и возврат false может по-прежнему приводить к повторной отрисовке компонента.


static getDerivedStateFromProps()


Код
    
  static getDerivedStateFromProps(props, state)
  

getDerivedStateFromProps вызывается непосредственно перед вызовом метода render как при начальном монтировании, так и при последующих обновлениях. Он должен возвращать объект, чтобы обновить состояние, или null, чтобы обновления не произошло.

Этот метод существует для редких случаев использования, когда состояние зависит от изменений props с течением времени. Например, это может быть удобно для реализации компонента <Transition>, который сравнивает своих предыдущих и следующих потомков, чтобы решить, кого из них нужно анимировать.

Производное состояние приводит к увеличению кода и делает ваши компоненты сложными для понимания. Убедитесь, что вы знакомы с более простыми альтернативами:

  • Если вам необходимо выполнить побочный эффект (например, извлечение данных или анимацию) в ответ на изменение props, используйте метод ЖЦ componentDidUpdate.

  • Если вы хотите пересчитывать некоторые данные только при смене props, используйте memoization.

  • Если вы хотите «сбросить» какое-то состояние при смене props, попробуйте либо сделать компонент полностью контролируемым, либо полностью неконтролируемым с помощью ключа.

Данный метод не имеет доступа к экземпляру компонента. Если необходимо, вы можете повторно использовать некоторый код между вызовом getDerivedStateFromProps() и другими методами класса, извлекая чистые функции props и state компонента за пределы определения класса.

Обратите внимание, что данный метод срабатывает при каждой отрисовке, независимо от её причин. Это отличается от UNSAFE_componentWillReceiveProps, который срабатывает только тогда, когда родитель вызывает повторную отрисовку, а не в результате локального вызова setState.


getSnapshotBeforeUpdate()


Код
    
  getSnapshotBeforeUpdate(prevProps, prevState)
  

getSnapshotBeforeUpdate() вызывается непосредственно перед тем, как последний результат отрисовки будет зафиксирован в DOM. Это позволяет вашему компоненту захватывать некоторую информацию из DOM (например, положение прокрутки) до того, как она может быть потенциально изменена. Любое значение, возвращаемое этим методом ЖЦ, будет передано в качестве параметра методу componentDidUpdate().

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

Значение снимка (или null) должно быть возвращено.


Код
    
  class ScrollingList extends React.Component {
    constructor(props) {
      super(props);
      this.listRef = React.createRef();
    }
  
    getSnapshotBeforeUpdate(prevProps, prevState) {
      // Мы добавляем новые элементы списка?
      // Нужно захватиить позицию скрола, затем мы сможем его отрегулировать.
      if (prevProps.list.length < this.props.list.length) {
        const list = this.listRef.current;
        return list.scrollHeight - list.scrollTop;
      }
      return null;
    }
  
    componentDidUpdate(prevProps, prevState, snapshot) {
      // Если у нас есть ненулевое значение snapshot, 
      // мы просто добавляем новые элементы.
      // Отрегулируем скролл, и теперь новые элементы 
      // не вытолкнут старые из видимой области.
      // (snapshot - это значение, возвращенное из getSnapshotBeforeUpdate)
      if (snapshot !== null) {
        const list = this.listRef.current;
        list.scrollTop = list.scrollHeight - snapshot;
      }
    }
  
    render() {
      return (
        <div ref={this.listRef}>{/* ...чат... */}</div>
      );
    }
  }
  

В приведенном выше примере важно считать свойство scrollHeight в getSnapshotBeforeUpdate, потому что могут быть задержки между вызовами методов ЖЦ фазы «отрисовки» (например, методом render) и фазы «фиксации» (такими как getSnapshotBeforeUpdate и componentDidUpdate).


4.2.2.3 Обработка ошибок


Границы ошибок - это компоненты React, которые отлавливают ошибки JavaScript в любом месте их дерева дочерних компонентов, регистрируют эти ошибки и отображают резервный интерфейс вместо поломанного дерева компонентов. Границы ошибок отлавливают ошибки при рендеринге, в методах жизненного цикла и в конструкторах всего поддерева.

Компонент класса становится границей ошибки, если он определяет один из (или оба) следующих методов ЖЦ: static getDerivedStateFromError() и componentDidCatch (error, info). Обновление состояния из этих методов ЖЦ позволяет вам захватить необработанную ошибку JavaScript в дереве ниже и отобразить аварийный интерфейс.

Используйте границы ошибок только для восстановления после непредвиденных исключений. Не пытайтесь использовать их для контроля потока.

Для получения дополнительной информации см. раздел "Границы ошибок".


Внимание!

Границы ошибок отлавливают ошибки только в компонентах ниже них в дереве. Граница ошибки не способна отловить ошибку внутри себя.


static getDerivedStateFromError()


Код
    
  static getDerivedStateFromError(error)
  

Добавлен в версии React 16.6

Данный метод ЖЦ вызывается после того, как компонент-потомок выбросил ошибку. Он получает выброшенную ошибку в качестве параметра, и должен вернуть значение для обновления состояния.


Код
    
  class ErrorBoundary extends React.Component {
    constructor(props) {
      super(props);
      this.state = { hasError: false };
    }
  
    static getDerivedStateFromError(error) {
      // Обновим состояние, и последующая отрисовка отобразит аварийный UI.
      return { hasError: true };
    }
  
    render() {
      if (this.state.hasError) {
        // Вы можете отобразить любой аварийный UI
        return <h1>Произошла ошибка.</h1>;
      }
  
      return this.props.children; 
    }
  }
  


Внимание!

getDerivedStateFromError() вызывается во время фазы «отрисовки», поэтому побочные эффекты в нем не допускаются. Вместо него в таких случаях используйте componentDidCatch().


componentDidCatch()


Код
    
  componentDidCatch(error, info)
  

Добавлен в версии React 16.0

Данный метод ЖЦ вызывается после того, как компонент-потомок выбросил ошибку. Он получает два параметра:

componentDidCatch() вызывается во время фазы фиксации, поэтому побочные эффекты разрешены. Его следует использовать для таких вещей, как логирование ошибок:


Код
    
  class ErrorBoundary extends React.Component {
    constructor(props) {
      super(props);
      this.state = { hasError: false };
    }
  
    static getDerivedStateFromError(error) {
      // Обновим состояние, и последующая отрисовка отобразит аварийный UI.
      return { hasError: true };
    }
  
    componentDidCatch(error, info) {
      // Пример "componentStack":
      //   in ComponentThatThrows (created by App)
      //   in ErrorBoundary (created by App)
      //   in div (created by App)
      //   in App
      logComponentStackToMyService(info.componentStack);
    }
  
    render() {
      if (this.state.hasError) {
        // Вы можете отобразить любой аварийный UI
        return <h1>Произошла ошибка.</h1>;
      }
  
      return this.props.children;
    }
  }
  


Замечание.

Чтобы отобразить аварийный UI в случае ошибки вы можете использовать componentDidCatch(), вызвав setState, но в последующих релизах так делать не рекомендуется. Для этой цели используйте static getDerivedStateFromError().


4.2.2.4 Устаревшие методы жизненного цикла


Методы жизненного цикла ниже помечены как «устаревшие». Они все еще работают, но мы не рекомендуем использовать их в новом коде. В данной статье вы можете больше узнать о миграции.


UNSAFE_componentWillMount()


Код
    
  UNSAFE_componentWillMount()
  


Внимание!

Данный метод ранее назывался componentWillMount. Это имя будет работать до версии 17. Используйте модификатор rename-unsafe-lifecycles для автоматического обновления ваших компонентов.

UNSAFE_componentWillMount() вызывается непосредственно перед монтированием. Он вызывается перед render(), поэтому синхронная установка состояния в этом методе не приведет к повторному рендерингу. Обычно вместо этого метода мы рекомендуем использовать constructor().

Избегайте введения каких-либо побочных эффектов или подписки на события в этом методе. Для таких случаев используйте метод componentDidMount().

Это единственный метод ЖЦ, вызываемый при серверной отрисовке.


UNSAFE_componentWillReceiveProps()


Код
    
  UNSAFE_componentWillReceiveProps(nextProps)
  


Внимание!

Данный метод ранее назывался componentWillReceiveProps. Это имя будет работать до версии 17. Используйте модификатор rename-unsafe-lifecycles для автоматического обновления ваших компонентов.


Внимание!

Использование этого метода ЖЦ часто приводит к ошибкам и неконсистентности.


  • Если вам необходимо выполнить побочный эффект (например, извлечение данных или анимацию) в ответ на изменение props, используйте метод ЖЦ componentDidUpdate.

  • Если вы хотите пересчитывать некоторые данные только при смене props, используйте memoization.

  • Если вы хотите «сбросить» какое-то состояние при смене props, попробуйте либо сделать компонент полностью контролируемым, либо полностью неконтролируемым с помощью ключа.

Для других случаев следуйте рекомендациям в данной статье о производном состоянии.


UNSAFE_componentWillReceiveProps() вызывается до того, как монтированный компонент получит новые свойства. Если вам нужно обновить состояние в ответ на изменения свойств (например, для его сброса), вы можете сравнить this.props и nextProps, и инициировать переход к новому состоянию, используя this.setState() в этом методе.

Обратите внимание, что если родительский компонент вызывает повторную отрисовку вашего компонента, этот метод будет вызываться, даже если props не изменились. Обязательно сравните текущие и следующие значения, если вы хотите только обрабатывать изменения.

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


UNSAFE_componentWillUpdate()


Код
    
  UNSAFE_componentWillUpdate(nextProps, nextState)
  


Внимание!

Данный метод ранее назывался componentWillUpdate. Это имя будет работать до версии 17. Используйте модификатор rename-unsafe-lifecycles для автоматического обновления ваших компонентов.

UNSAFE_componentWillUpdate() вызывается непосредственно перед отрисовкой при получении новых свойств или состояния. Используйте это как возможность выполнить какую-либо подготовку до того, как произойдет обновление. Этот метод не вызывается для первоначальной отрисовки.

Обратите внимание, что вы не можете вызвать this.setState() здесь. Более того, здесь вы не должны делать ничего (например, вызывать действие Redux), что инициировало бы обновление компонента React до того, как отработает UNSAFE_componentWillUpdate().

Как правило данный метод может быть заменен на componentDidUpdate(). Если вы в этом методе производили доступ к DOM (например, чтобы сохранить позицию прокрутки), то можете переместить эту логику в getSnapshotBeforeUpdate().


Замечание.

UNSAFE_componentWillUpdate() не будет вызван, если shouldComponentUpdate() возвращает false.


4.2.2.5 Другие API


В отличие от методов жизненного цикла, описанных выше (которые React вызывает для вас сам), нижеперечисленные методы могут быть вызваны из ваших компонентов.

Их два: setState() и forceUpdate().


setState()


Код
    
  setState(updater[, callback])
  

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

Думайте о setState() как о запросе, а не как о немедленной команде для обновления компонента. Для улучшения производительности React может задержать ее, а затем обновить несколько компонентов за один проход. React не гарантирует немедленного применения изменений состояния.

setState() не всегда сразу обновляет компонент. Он может добавить в очередь или отложить обновление до наиболее поздней версии. Это делает чтение this.state прямо после вызова setState() потенциальной ловушкой. Вместо этого используйте componentDidUpdate или обратный вызов setState: (setState (updater, callback)), любой из которых гарантированно будет срабатывать после применения обновления. Если вам необходимо установить состояние на основе предыдущего состояния, читайте об аргументе updater ниже.

setState() всегда приведет к повторной отрисовке, кроме случаев, когда shouldComponentUpdate() возвращает false. Если используются изменяемые объекты, и логика условной отрисовки не может быть реализована в shouldComponentUpdate(), вызов setState() только тогда, когда новое состояние отличается от предыдущего состояния, позволит избежать ненужных повторных отрисовок.

Первый аргумент updater - это функция с сигнатурой:


Код
    
  (prevState, props) => stateChange
  

prevState - ссылка на предыдущее состояние. Оно не должно быть непосредственно изменено. Вместо этого, изменения должны быть представлены путем создания нового объекта на основе prevState и props. Например, предположим, что мы захотели изменить значение в состоянии с помощью props.delta:


Код
    
  this.setState((prevState, props) => {
    return {temperature: prevState.temperature + props.delta};
  });
  

Как prevState, так и props, полученные функцией обновления гарантировано будут актуальными. Возвращаемый результат функции обновления будет неглубоко смерджен с prevState.

Второй параметр для setState() - это дополнительная функция обратного вызова, которая будет выполняться после завершения setState и повторной отрисовки компонента. Обычно вместо неё мы рекомендуем использовать componentDidUpdate().

Вы можете передать объект в качестве первого аргумента функции setState() вместо функции:


Код
    
  setState(stateChange, [callback])
  

Такой вызов приведёт к неглубокому слиянию stateChange в новое состояние, например, чтобы показать диалог:


Код
    
  this.setState({isDialogShowed: true})
  

Эта форма setState() также асинхронна, и несколько вызовов в течение одного и того же цикла могут быть объединены вместе. Например, если вы пытаетесь увеличить счетчик более одного раза в одном цикле, это будет эквивалентно:


Код
    
  Object.assign(
    previousState,
    {counter: state.counter + 1},
    {counter: state.counter + 1},
    ...
  )
  

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


Код
    
  this.setState((prevState) => {
    return {counter: prevState.counter + 1};
  });
  

Более детальная информация находится в главе « Состояние и жизненный цикл ».


forceUpdate()


Код
    
  component.forceUpdate(callback)
  

По умолчанию, когда свойства или состояние вашего компонента изменяются, ваш компонент будет повторно отрисован. Если метод render() зависит от каких-то других данных, вы можете сказать React, что компонент нуждается в повторной перерисовке, вызвав forceUpdate().

Вызов forceUpdate() приведет к вызову render() для компонента, пропуская shouldComponentUpdate(). Будут вызваны обычные методы жизненного цикла дочерних компонентов, включая метод shouldComponentUpdate() для каждого потомка. React будет по-прежнему обновлять DOM только в случае изменения разметки.

В большинстве случаев вы должны стараться избегать использования forceUpdate() и считывать данные только из this.props и this.state в методе render().



4.2.3 Свойства класса



defaultProps

defaultProps можно определить как свойство самого класса компонента, чтобы установить свойства по умолчанию для класса. Это используется для undefined свойств, но не для null свойств. Например:


Код
    
  class Alert extends React.Component {
    // ...
  }

  Alert.defaultProps = {
    type: 'success'
  };
  

Если props.type не будет предоставлен, по умолчанию он будет установлен в 'success':


Код
    
  render() {
    return <Alert /> ; // props.type будет установлено в 'success'
  }
  

Если для свойства props.type установлено значение null, оно останется null:


displayName

Строковое свойство displayName используется для сообщений отладки. Обычно вам не нужно явно указывать его, поскольку оно берётся из имени функции или класса, которые определяют компонент. Возможно, вы захотите установить его явно, если хотите отобразить другое имя для целей отладки или когда вы создаете компонент более высокого порядка, см. раздел « Обёртывание отображаемого имени для облегчения отладки ».



4.2.4 Свойства экземпляра



props

this.props содержит свойства, которые были определены вызывающим компонентом данного компонента. См. « Компоненты и свойства » для ознакомления со свойствами.

В частности, this.props.children - специальное свойство, обычно определяемое дочерними тегами в выражении JSX, а не на в самом теге.


state

Состояние содержит данные, специфичные для этого компонента, которые могут меняться со временем. Состояние определяется пользователем, и оно должно быть простым объектом JavaScript.

Если вы не используете что-то в render(), оно не должно находиться в состоянии. Например, вы можете поместить идентификаторы таймера непосредственно в экземпляр.

См. « Состояние и жизненный цикл » для получения дополнительной информации о состоянии.

Никогда не изменяйте this.state напрямую, так как вызов setState() впоследствии может заменить ваше изменение. Обращайтесь с this.state, как если бы оно было неизменяемым.