JS: React
Теория: Жизненный цикл компонента
При правильном использовании React большая часть компонентов состоит из метода render и обработчиков событий:
Но не все задачи решаются так просто. Представьте себе компонент <Clock />, имитирующий цифровые часы в формате чч:мм:сс. Заготовка:
Этот компонент отображает текущее время. Теперь нужно придумать, как его обновлять. Часы, в отличие от обычных компонентов, не ожидают действий от пользователя. Они обновляются каждую секунду самостоятельно. Возникает цепочка: происходит событие => меняется текущее время => React вызывает render и меняет DOM. Итак, состояние инициализируется текущим временем:
Компонент по-прежнему показывает текущее время на момент отрисовки/перерисовки компонента, но теперь он готов к изменению. Время относится к периодическим событиям, для которых используются таймеры. Для <Clock /> подойдет setInterval. Таймер должен быть установлен сразу после отрисовки часов и должен быть очищен при удалении компонента из дерева элементов.
Где запускать таймер? render вызывается на каждое изменение состояния, а значит он не подходит. Ведь тогда <Clock /> будет запускать новый таймер каждую секунду. Конструктор кажется более подходящим местом, но здесь ожидает сюрприз. Вызов конструктора и отрисовка часов в DOM-дереве, в общем случае — два независимых события. Посмотрите на код:
Эти часы еще не находятся в DOM-дереве, но уже вовсю работают и обновляются. Стоит ли об этом беспокоиться? Да, такое поведение крайне неожиданно, оно мешает тестированию и расходует процессорное время. Кроме того, конструктор никак не помогает с удалением таймера.
Каждый компонент React проходит несколько стадий в процессе своей жизни: он создается, затем добавляется в DOM, затем может обновляться (например, при изменении пропсов или состояния), и, наконец, удаляется из дерева. Этот процесс называют жизненным циклом компонента (Component Lifecycle). React предоставляет набор методов, которые позволяют встроиться в этот процесс. Например, запуск часов логичнее всего сделать сразу после их отрисовки. В этом поможет метод componentDidMount. Он вызывается сразу после отрисовки компонента. Происходит это ровно один раз.
Обратите внимание на то, как сохраняется идентификатор таймера внутри объекта. Он не участвует в представлении, поэтому нет необходимости сохранять его в состоянии.
Теперь нужно выполнить очистку таймера. Для этого подойдет метод componentWillUnmount, который выполняется прямо перед удалением компонента из DOM.
Часы приобрели законченный вид.
Итак, вы узнали два метода, позволяющих встраиваться в жизненный цикл компонента, но их значительно больше. Они делятся на три независимые группы:
Монтирование (Mounting)
Эти методы вызываются по порядку во время создания объекта и вставки его в DOM.
constructor()static getDerivedStateFromProps()render()componentDidMount()
Обновление (Updating)
Обновление может происходить при изменении свойств или состояния. Эти методы вызываются по порядку во время перерисовки:
static getDerivedStateFromProps()shouldComponentUpdate()render()getSnapshotBeforeUpdate()componentDidUpdate()
Удаление или демонтирование (Unmounting)
В эту группу входит один метод. Он вызывается во время удаления компонента из DOM.
componentWillUnmount()
Такое количество методов объясняется сложностью реальной разработки. Но на практике лишь некоторые используются регулярно. К таким методам относится componentDidMount. С его помощью устанавливают таймеры, выполняют AJAX-запросы, меняют DOM в обход React. Последнее бывает нужно при интеграции со сторонними библиотеками.




