- PVSM.RU - https://www.pvsm.ru -
В сегодняшней части перевода учебного курса по React вашему вниманию будет представлен обзор методов жизненного цикла компонентов.
→ Часть 1: обзор курса, причины популярности React, ReactDOM и JSX [2]
→ Часть 2: функциональные компоненты [3]
→ Часть 3: файлы компонентов, структура проектов [4]
→ Часть 4: родительские и дочерние компоненты [5]
→ Часть 5: начало работы над TODO-приложением, основы стилизации [6]
→ Часть 6: о некоторых особенностях курса, JSX и JavaScript [7]
→ Часть 7: встроенные стили [8]
→ Часть 8: продолжение работы над TODO-приложением, знакомство со свойствами компонентов [9]
→ Часть 9: свойства компонентов [10]
→ Часть 10: практикум по работе со свойствами компонентов и стилизации [11]
→ Часть 11: динамическое формирование разметки и метод массивов map [12]
→ Часть 12: практикум, третий этап работы над TODO-приложением [13]
→ Часть 13: компоненты, основанные на классах [14]
→ Часть 14: практикум по компонентам, основанным на классах, состояние компонентов [15]
→ Часть 15: практикумы по работе с состоянием компонентов [16]
→ Часть 16: четвёртый этап работы над TODO-приложением, обработка событий [17]
→ Часть 17: пятый этап работы над TODO-приложением, модификация состояния компонентов [18]
→ Часть 18: шестой этап работы над TODO-приложением [19]
→ Часть 19: методы жизненного цикла компонентов [1]
→ Оригинал [20]
Одной из особенностей разработки React-приложений является тот факт, что мы пишем довольно простой JavaScript-код, который приводит в действие внутренние механизмы React и тем самым даёт нам замечательные возможности по разработке интерфейсов приложений и по работе с данными. При этом компоненты, которыми мы пользуемся, в течение своего жизненного цикла, проходят через определённые этапы. Часто то, что происходит с компонентом в приложении, сравнивают с жизнью человека. Люди рождаются, живут, в их жизни случаются некие значимые события, после чего они умирают. Компоненты React в этом похожи на людей, так как они тоже «рождаются», «живут» и «умирают». Работая с компонентами, мы можем реагировать на то, что с ними происходит, благодаря методам их жизненного цикла, которые вызываются в особенные моменты их «жизни».
Недавно команда разработчиков React признала устаревшими три метода жизненного цикла компонентов. Мы эти методы, всё же, рассмотрим, так как ими всё ещё можно пользоваться, и так как они могут встретиться вам в существующем коде. Кроме того, в React были добавлены два новых метода жизненного цикла компонентов, о которых мы поговорим на следующем занятии.
Мы рассмотрим только самые важные методы, которые наиболее актуальны для тех, кто только приступил к изучению React. Когда же вы продолжите осваивать эту библиотеку, вы сможете поэкспериментировать и с другими методами.
Вот [21] хороший материал, посвящённый методам жизненного цикла компонентов React, которые были актуальны до выхода версии React 16.3. Здесь [22], в публикации из официального блога разработчиков React, можно узнать об изменениях, которые произошли в React 16.3.
Теперь начнём разговор о методах жизненного цикла компонентов React, с которыми вам придётся встречаться чаще всего.
Мы, как всегда, будем пользоваться здесь демонстрационным проектом. В данном случае мы начинаем со стандартного проекта, созданного средствами create-react-app, в файле App.js
которого содержится следующий код:
import React, {Component} from "react"
class App extends Component {
constructor() {
super()
this.state = {}
}
render() {
return (
<div>
Code goes here
</div>
)
}
}
export default App
Для начала давайте взглянем на метод, которым вы, работая с компонентами, основанными на классах, уже пользовались. Это — метод render()
.
Часто его, говоря о методах жизненного цикла компонентов, не упоминают. Думаю, что этот метод, если сравнивать компонент с человеком, можно сравнить с одеванием перед выходом на улицу. Задачей этого метода является определение того, что будет выведено на экран, то есть того, как будет выглядеть компонент. Метод render()
в процессе жизни компонента может быть вызван множество раз. Так, когда React определяет, что что-то, относящееся к компоненту, изменилось, наподобие состояния или свойств, то есть что-то такое, что может повлиять на внешний вид компонента, React может вызвать этот метод. Это можно сравнить, если продолжить аналогию с людьми, с тем, что человек может решить переодеться. Например для того, чтобы, после рабочего дня, подготовиться к некоему праздничному мероприятию.
Теперь рассмотрим ещё один метод жизненного цикла компонентов — componentDidMount()
. Этот метод объявляют, точно так же, как и любые другие методы компонентов, основанных на классах, в теле класса компонента:
componentDidMount() {
}
Этот метод вызывается в момент жизненного цикла компонента, который можно сравнить с «рождением» этого компонента. Этот метод срабатывает один раз после того, как компонент будет смонтирован (вставлен) в дерево DOM. При этом, например, если после изменения неких данных, влияющих на внешний вид компонента, будет выполнен его повторный рендеринг, метод componentDidMount()
вызван не будет. Происходит это из-за того, что при выполнении подобных операций не производится изъятие компонента из дерева DOM и его последующее повторное включение в состав дерева.
Метод componentDidMount()
обычно используют для выполнения обращений к неким API, в случаях, когда разработчику нужны данные из внешних источников. Предположим, компонент, который мы тут рассматриваем, на самом деле называется TodoList
и представляет собой компонент, формирующий список дел в Todo-приложении. Метод componentDidMount()
такого компонента может выполнять загрузку материалов из серверной базы данных, необходимых для корректного вывода на страницу хранящегося на сервере списка дел. В результате после того, как монтирование компонента завершено, мы, в методе componentDidMount()
, можем загрузить данные, необходимые для правильного отображения компонента на странице. Мы ещё поговорим о загрузке данных, необходимых компонентам, а пока же можете запомнить, что это — наиболее часто встречающийся вариант использования метода componentDidMount()
.
Следующий метод жизненного цикла компонентов, который мы обсудим, называется componentWillReceiveProps()
. Этот метод можно сравнить с тем, что происходит, когда кто-то получает от кого-то подарок. Так, компонент может получать свойства от родительского компонента. Каждый раз, когда компонент принимает свойства, вызывается этот метод. При этом данный метод вызывается каждый раз, когда родительский компонент передаёт свойства дочернему компоненту, а не только тогда, когда это случается в первый раз. Например, если родительский компонент решит поменять свойства, переданные дочернему компоненту, то мы, в методе componentWillReceiveProps()
, сможем, например, проверить, отличаются ли новые свойства от тех, что уже были переданы компоненту. Дело в том, что если новые свойства не отличаются от старых, это значит, что их поступление ничего не меняет, а значит — мы можем, выяснив это, больше ничего не делать. Если же новые свойства отличаются от старых, мы можем выполнить некие действия. Обычно этот метод объявляют в теле класса компонента в таком виде:
componentWillReceiveProps(nextProps) {
}
Тут обычно используется, в качестве имени параметра, nextProps
, но назвать этот параметр можно как угодно. Для того чтобы сравнить некое конкретное свойство, которое уже было передано компоненту, с тем, что уже было ему передано ранее, и принять решение о дальнейших действиях, можно воспользоваться такой конструкцией:
componentWillReceiveProps(nextProps) {
if (nextProps.whatever !== this.props.whatever) {
// сделать тут что-то важное
}
}
Обычно этот метод используют именно так.
Однако, как уже было сказано, после выхода React 16.3 некоторые методы жизненного цикла компонентов были признаны устаревшими, и componentWillReceiveProps()
— это один из таких методов.
До выхода React 17 этими устаревшими методами всё ещё можно пользоваться, хотя лучше этого не делать. Если без рассматриваемого метода никак не обойтись — его нужно назвать UNSAFE_componentWillReceiveProps()
. После выхода React 17 имя метода componentWillReceiveProps()
не будет означать ничего особенного.
Об этом методе полезно знать для того, чтобы иметь возможность понимать устаревший код, но при разработке современных React-приложений он уже использоваться не будет.
Ещё один интересный метод жизненного цикла компонентов называется shouldComponentUpdate()
. Он, если продолжить сравнение компонента с человеком, напоминает момент, когда человек размышляет о том, надо ли ему переодеться или нет. В обычных условиях, если React не вполне уверен в том, надо ли повторно отрендерить компонент, он его, на всякий случай, всё же отрендерит. При этом неважно — нужно ли это, в соответствии с логикой приложения, или нет.
Это приводит к тому, что React повторно рендерит компоненты даже в тех случаях, когда ничего, имеющего отношение к компоненту, не меняется. Подобное может привести к замедлению приложения, так как по такому принципу React обрабатывает все компоненты, входящие в состав приложения. Метод shouldComponentUpdate()
даёт разработчику возможность оптимизировать приложение. Здесь можно реализовать некую логику, помогающую выяснить необходимость обновления компонента. Этот метод обычно объявляют так:
shouldComponentUpdate(nextProps, nextState) {
// вернуть true если компонент нуждается в обновлении
// вернуть false в противном случае
}
При этом из этого метода, если компонент нуждается в повторном рендеринге, с учётом новых свойств и состояния, нужно вернуть true
. В противном случае из него нужно вернуть false
. Собственно говоря, возврат false
из этого метода приводит к тому, что обновление компонента не выполняется и приложение работает быстрее, но, делая это, нужно быть уверенным в том, что компоненту действительно не требуется повторный рендеринг. Если же компоненту нужно обновиться, а этот метод вернул false
— это приведёт к появлению ошибок, с которыми будет сложно бороться.
Ещё один метод жизненного цикла компонентов, о котором мы поговорим, называется componentWillUnmount()
. Этот метод знаменует собой окончание «жизни» компонента — тот момент, когда он удаляется из дерева DOM и исчезает с экрана.
Этот метод, в основном, используется для того, чтобы освобождать ресурсы, занятые компонентом и навести перед его удалением порядок. Например, если в методе componentDidMount()
было настроено нечто вроде прослушивателя событий, благодаря которому, когда пользователь прокручивает страницу, выполняется некий код, именно в componentWillUnmount()
можно удалить такой прослушиватель событий. На самом же деле, у этого метода есть множество вариантов применения, которые направлены на то, чтобы убрать из приложения всё, что окажется ненужным после исчезновения компонента.
Вот полный код нашего компонента App
, в который добавлены методы жизненного цикла:
import React, {Component} from "react"
class App extends Component {
constructor() {
super()
this.state = {}
}
componentDidMount() {
// загрузить данные, необходимые для корректного отображения компонента
}
componentWillReceiveProps(nextProps) {
if (nextProps.whatever !== this.props.whatever) {
// сделать тут что-то важное
}
}
shouldComponentUpdate(nextProps, nextState) {
// вернуть true если компонент нуждается в обновлении
// вернуть false в противном случае
}
componentWillUnmount() {
// навести порядок после удаления компонента
// (например - убрать прослушиватели событий)
}
render() {
return (
<div>
Code goes here
</div>
)
}
}
export default App
На этом мы завершаем данное занятие, хотя надо отметить, что методы жизненного цикла компонентов React не ограничиваются теми, что мы сегодня рассмотрели.
→ Оригинал [23]
Как уже было сказано на предыдущем занятии, когда вышел React 16.3, было сообщено о том, что три метода жизненного цикла компонентов устарели. Это методы componentWillMount()
, componentWillReceiveProps()
и componentWillUpdate()
. Также было сообщено о появлении двух новых методов. Это — статический метод getDerivedStateFromProps()
и метод getSnapshotBeforeUpdate()
. Нельзя сказать, что эти методы сыграют важную роль на будущих занятиях этого курса, но мы, несмотря на это, здесь с ними ознакомимся.
Экспериментировать будем в том же проекте, который мы использовали в прошлый раз.
Вот как выглядит объявление метода getDerivedStateFromProps()
:
static getDerivedStateFromProps(props, state) {
}
Обратите внимание на ключевое слово static
перед именем метода. Он, на основании принятых им свойств, должен возвратить обновлённое состояние. Он используется в тех случаях, когда некий компонент должен принимать входящие свойства, получаемые им от компонента-родителя, и настраивать своё состояние, основываясь на этих свойствах. Подробности об этом методе можно почитать здесь [24]. В этом материале, опубликованном в блоге React, речь идёт о том, что применение этого метода оправдано далеко не во всех тех ситуациях, в которых он, как кажется, может пригодиться. Его неправильное использование может приводить к различным ошибкам, к падению производительности приложений, поэтому пользоваться им следует с осторожностью. Не следует пытаться решать с его помощью задачи, для решения которых он не предназначен. Вот [25] документация к этому методу.
Теперь поговорим о методе getSnapshotBeforeUpdate()
. Вот как выглядит его объявление в теле класса:
getSnapshotBeforeUpdate() {
}
Его можно рассматривать как метод жизненного цикла, который позволяет создавать нечто вроде резервной копии того, что имеется в компоненте перед его обновлением. Она напоминает мгновенный снимок состояния приложения. При этом нужно отметить, что разработчики React говорят о том, что сфера применения этого метода ограничена. Вот [26] документация по нему.
Сегодня мы поговорили о методах жизненного цикла компонентов. Когда вы продвинетесь в деле разработки React-приложений, они вам, безусловно, пригодятся. На дальнейших занятиях этого курса мы ещё встретимся с этими методами, в частности, с componentDidMount()
. В следующий раз поговорим об условном рендеринге.
Уважаемые читатели! Если вы профессионально разрабатываете React-приложения — просим рассказать о том, как вы пользуетесь методами жизненного цикла компонентов.
Автор: ru_vds
Источник [27]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/310102
Ссылки в тексте:
[1] Image: https://habr.com/ru/company/ruvds/blog/441578/
[2] Часть 1: обзор курса, причины популярности React, ReactDOM и JSX: https://habr.com/post/432636/
[3] Часть 2: функциональные компоненты: https://habr.com/post/433400/
[4] Часть 3: файлы компонентов, структура проектов: https://habr.com/post/433404/
[5] Часть 4: родительские и дочерние компоненты: https://habr.com/company/ruvds/blog/434118/
[6] Часть 5: начало работы над TODO-приложением, основы стилизации: https://habr.com/company/ruvds/blog/434120/
[7] Часть 6: о некоторых особенностях курса, JSX и JavaScript: https://habr.com/company/ruvds/blog/435466/
[8] Часть 7: встроенные стили: https://habr.com/company/ruvds/blog/435468/
[9] Часть 8: продолжение работы над TODO-приложением, знакомство со свойствами компонентов: https://habr.com/company/ruvds/blog/435470/
[10] Часть 9: свойства компонентов: https://habr.com/company/ruvds/blog/436032/
[11] Часть 10: практикум по работе со свойствами компонентов и стилизации: https://habr.com/company/ruvds/blog/436890/
[12] Часть 11: динамическое формирование разметки и метод массивов map: https://habr.com/company/ruvds/blog/436892/
[13] Часть 12: практикум, третий этап работы над TODO-приложением: https://habr.com/company/ruvds/blog/437988/
[14] Часть 13: компоненты, основанные на классах: https://habr.com/ru/company/ruvds/blog/437990/
[15] Часть 14: практикум по компонентам, основанным на классах, состояние компонентов: https://habr.com/ru/company/ruvds/blog/438986/
[16] Часть 15: практикумы по работе с состоянием компонентов: https://habr.com/ru/company/ruvds/blog/438988/
[17] Часть 16: четвёртый этап работы над TODO-приложением, обработка событий: https://habr.com/ru/company/ruvds/blog/439982/
[18] Часть 17: пятый этап работы над TODO-приложением, модификация состояния компонентов: https://habr.com/ru/company/ruvds/blog/439984/
[19] Часть 18: шестой этап работы над TODO-приложением: https://habr.com/ru/company/ruvds/blog/440662/
[20] Оригинал: https://scrimba.com/p/p7P5Hd/cewQ2Sq
[21] Вот: https://engineering.musefind.com/react-lifecycle-methods-how-and-when-to-use-them-2111a1b692b1
[22] Здесь: https://reactjs.org/blog/2018/03/29/react-v-16-3.html#component-lifecycle-changes
[23] Оригинал: https://scrimba.com/p/p7P5Hd/cEkyPH2
[24] здесь: https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html
[25] Вот: https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops
[26] Вот: https://reactjs.org/docs/react-component.html#getsnapshotbeforeupdate
[27] Источник: https://habr.com/ru/post/441578/?utm_source=habrahabr&utm_medium=rss&utm_campaign=441578
Нажмите здесь для печати.