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

Обновлять:

React 16.3 представил еще два метода жизненного цикла и отказался от некоторых из них, не забудьте проверить продолжение на https://medium.com/@baphemot/understanding-react-react-16-3-component-life -cycle-23129bc7a705

конструктор

конструкторы являются основой ООП - это специальная функция, которая будет вызываться всякий раз, когда создается новый объект. Очень важно вызывать специальную функцию super в случаях, когда наш класс расширяет любой другой класс, который также имеет определенный конструктор. Вызов этой специальной функции вызовет конструктор нашего родительского класса и позволит ему инициализировать себя. Вот почему у нас есть доступ к this.props только после первоначального вызова super.

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

Это также единственное место, где вы должны изменить / установить состояние, напрямую перезаписав поля this.state. Во всех остальных случаях не забудьте использовать this.setState

DO

  • установить начальное состояние
  • если не используется синтаксис свойств класса - подготовьте все поля класса и привяжите функции, которые будут переданы как обратные вызовы

НЕЛЬЗЯ

  • вызывать какие-либо побочные эффекты (вызовы AJAX и т. д.)

устарело - componentWillMount

Это как-то особый случай - componentWillMount не сильно отличается от конструктора - он также вызывается один раз только в начальном жизненном цикле монтирования. Исторически было несколько причин использовать componentWillMountover constructor см. Эту проблему с реакцией-редукцией, но имейте в виду, что описанная здесь практика устарела.

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

Кроме того, с изменениями в React Fiber (после бета-версии React 16) эта функция может в конечном итоге вызываться несколько раз до вызова начального render, что может привести к запуску нескольких побочных эффектов. В связи с этим не рекомендуется использовать эту функцию для операций, вызывающих побочные эффекты.

Важно отметить, что эта функция вызывается при использовании рендеринга на стороне сервера, в то время как ее аналог - componentDidMount в этом случае будет вызываться не на сервере, а на клиенте. Поэтому, если в серверной части требуется побочный эффект, эту функцию следует использовать как исключение.

setState, используемый в этой функции, является «бесплатным» и не запускает повторный рендеринг.

DO

  • обновить состояние через this.setState
  • выполнить оптимизацию в последнюю минуту
  • вызывают побочные эффекты (вызовы AJAX и т. д.) только в случае рендеринга на стороне сервера

НЕЛЬЗЯ

  • вызывать какие-либо побочные эффекты (вызовы AJAX и т. д.) на стороне клиента

устарело - componentWillReceiveProps (nextProps)

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

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

Имейте в виду, что из-за того, что функция вызывается со всеми реквизитами, даже теми, которые не изменились, ожидается, что разработчики осуществят проверку, чтобы определить, изменилось ли фактическое значение, например:

componentWillReceiveProps(nextProps) {
  if(nextProps.myProp !== this.props.myProps) {
    // nextProps.myProp has a different value than our current prop
    // so we can perform some calculations based on the new value
  }
}

В связи с тем, что в React Fiber (после 16 бета) эта функция может вызываться несколько раз до фактического вызова renderfunction, не рекомендуется использовать здесь какие-либо операции, вызывающие побочные эффекты.

DO

  • синхронизировать состояние с реквизитом

НЕЛЬЗЯ

  • вызывать какие-либо побочные эффекты (вызовы AJAX и т. д.)

shouldComponentUpdate (nextProps, nextState, nextContext)

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

Эта функция будет вызываться изнутри со следующими значениями свойств, состояния и объекта. Разработчик может использовать их, чтобы убедиться, что изменение требует повторного рендеринга или нет, и вернуть false, чтобы предотвратить повторный рендеринг. В противном случае ожидается возврат true.

DO

  • использовать для повышения производительности неэффективных компонентов

НЕЛЬЗЯ

  • вызывать какие-либо побочные эффекты (вызовы AJAX и т. д.)
  • позвонить this.setState

устарело - componentWillUpdate (nextProps, nextState)

Если функция shouldComponentUpdate не реализована или решено, что компонент должен обновляться в этом цикле рендеринга, будет вызвана другая функция жизненного цикла. Эта функция обычно используется для выполнения синхронизации состояния и свойств, когда части вашего состояния основаны на свойствах.

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

Как и все другие componentWill* функции, эта функция могла в конечном итоге вызываться несколько раз до render, поэтому ей не рекомендуется выполнять здесь операции, вызывающие побочные эффекты.

DO

  • синхронизировать состояние с реквизитом

НЕЛЬЗЯ

  • вызывать какие-либо побочные эффекты (вызовы AJAX и т. д.)

componentDidUpdate (prevProps, prevState, prevContext)

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

В связи с тем, что это единственная функция, которая гарантированно будет вызываться только один раз в каждом цикле повторного рендеринга, рекомендуется использовать эту функцию для любых операций, вызывающих побочные эффекты. Подобно componentWillUpdate и componentWillReceiveProps эта функция вызывается с объектными картами предыдущих свойств, состояния и контекста, даже если с этими значениями не произошло фактических изменений. Из-за этого разработчики должны вручную проверять, изменилось ли заданное значение, и только затем выполнять различные операции обновления:

componentDidUpdate(prevProps) {
  if(prevProps.myProps !== this.props.myProp) {
    // this.props.myProp has a different value
    // we can perform any operations that would 
    // need the new value and/or cause side-effects 
    // like AJAX calls with the new value - this.props.myProp
  }
}

DO

  • вызывать побочные эффекты (вызовы AJAX и т. д.)

НЕЛЬЗЯ

  • вызовите this.setState, так как это приведет к повторному рендерингу

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

componentDidCatch (errorString, errorInfo)

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

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

componentDidCatch(errorString, errorInfo) {
  this.setState({
    error: errorString
  });
  ErrorLoggingTool.log(errorInfo);
}
render() {
  if(this.state.error) return <ShowErrorMessage error={this.state.error} />
  return (
    // render normal component output
  );
}

При возникновении ошибки функция будет вызвана с:

  • errorString - .toString() сообщение об ошибке
  • errorInfo - объект с одним полем componentStack, который представляет трассировку стека до места возникновения ошибки, например:
in Thrower
    in div (created by App)
    in App

componentDidMount

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

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

DO

  • вызывать побочные эффекты (вызовы AJAX и т. д.)

НЕЛЬЗЯ

  • вызовите this.setState, так как это приведет к повторному рендерингу

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

componentWillUnmount

Используйте эту функцию для «очистки» после компонента, если он использует таймеры (setTimeout, setInterval), открывает сокеты или выполняет какие-либо операции, которые нам нужно закрыть / удалить, когда они больше не нужны.

DO

  • удалить любые таймеры или слушатели, созданные в течение срока службы компонента

НЕЛЬЗЯ

  • вызов this.setState, запуск новых слушателей или таймеров

Компонентные циклы

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

Создание компонента

Первый цикл - это создание компонента, которое обычно происходит при первом обнаружении компонента в проанализированном дереве JSX:

Повторный рендеринг компонента из-за повторного рендеринга родительского компонента

Повторная отрисовка компонента из-за внутренних изменений (например, вызов this.setState())

Повторная отрисовка компонента из-за вызова this.forceUpdate

Повторная отрисовка компонента из-за обнаружения ошибки

Введен в React 16 как «границы ошибок». Компонент может определять специальный уровень, который может обнаруживать ошибки и предоставлять новый метод жизненного цикла - componentDidCatch, который позволяет разработчикам обеспечивать действия по самовосстановлению для восстановления или постепенной обработки ошибок.

Приветствуем @James_k_nelson, который недавно опубликовал симулятор componentWillReceiveProps, который вы можете найти и поиграть на https://reactarmory.com/guides/lifecycle-simulators