React17, или как избавиться от «componentWillReceiveProps»?

Как вы, возможно, уже знаете, с выпуском React 16.3 некоторые устаревшие жизненные циклы устарели.

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

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

Так что же теперь происходит?

Начиная с версии 17, поддержка React для некоторых жизненных циклов изменится:

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

С этого момента будут работать только новые имена жизненного цикла «UNSAFE_». Это оставляет нам несколько вариантов:

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

Я бы порекомендовал выбрать последний вариант.

Тогда перейдем к делу

Нам нужно избавиться от трех жизненных циклов, поэтому я постараюсь рассмотреть каждый из них отдельно.

componentWillMount

Это просто. Просто используйте вместо этого constructor.

Выглядит неплохо, но с некоторыми оговорками. Не рекомендуется иметь побочные эффекты (получение api, возможно, некоторые вычисления) внутри constructor. Лучше переместить их в componentDidMount, а не в конструктор. Обратной стороной является то, что он выполняется после render(), поэтому в зависимости от побочного эффекта вы можете выполнить повторную визуализацию.



componentWillUpdate

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

Этот перехватчик событий в основном componentWillReceiveProps, но хуже. Это происходит непосредственно перед рендерингом, но вы не можете использовать this.setState().

Тем не менее, это полезно, поскольку дает вам возможность управлять компонентом непосредственно перед тем, как он получит новые свойства или состояние. Я бы использовал его в основном для анимации, потому что он позволяет вам предопределить некоторые начальные условия для узлов DOM.

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

getSnapshotBeforeUpdate(prevProps, prevState)

getSnapshotBeforeUpdate() вызывается прямо перед тем, как последний отрендеренный вывод будет зафиксирован, например. ДОМ. Он возвращает снимок (по умолчанию: NULL), который является третьим параметром для componentDidUpdate(prevProps, prevState, snapshot)

componentWillReceiveProps

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

Побочные эффекты

Рассмотрим этот пример: у меня есть интеграция с домофоном, но ее нужно показывать на определенных маршрутах.

componentDidUpdate вызывается только после обновления, а нет при первоначальном рендеринге.

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

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

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

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

Этот метод полезен только для обработки состояния, а все остальные побочные эффекты следует переместить в componentDidUpdate. Кроме того, это static метод, и его доступ к внутренним методам класса ограничен.

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

Допустим, мне нужно сравнить два массива внутри getDerivedStateFromProps. Я не могу получить доступ к внутренним функциям компонента, используя this.compareArrays() ,, поэтому ничто не говорит против создания чистой функции compareArrays вне моего компонента списка.

Спасибо, что прочитали эту статью. Все цитаты взяты из официального React doc.

Свяжитесь со мной в LinkedIn или подпишитесь на меня на GitHub.