В этой статье подробно рассказывается об использовании жизненного цикла React и жизненного цикла каждого этапа, а также подробно демонстрируется пример кода.расположение кода
Без лишних слов, давайте сфотографируем
Изображение выше основано на диаграмме жизненного цикла после React 16.4. Если это кажется неправильным, сначала проверьте версию React.
Жизненный цикл React в деталях
Функции жизненного цикла для каждой фазы
конструктор конструктор
Вызывается перед монтированием компонента React, реализуетReact.Component
Когда конструктор подкласса добавляет super(props) в первую строку.
Конструкторы React обычно используются только для двух целей:
- путем присвоения объекта
this.state
для инициализации локальногоstate
- Привязать метод обработчика событий к экземпляру
Если нет инициализированного состояния (state
), и не имеет связанного метода, обычно не требуемого дляReact
Компоненты реализуют конструктор.
Нет необходимости вызывать конструктор
setState()
, просто установите начальное состояние наthis.state
Вот и все.
static getDerivedStateFromProps(nextProps, prevState)
getDerivedStateFromProps
Вызывается перед каждым вызовом метода рендеринга. Включая инициализацию и последующие обновления.
Содержит два параметра: первый параметр подлежит обновлению
props
значение, второй параметр является предыдущимstate
стоимость
Возвращаемое значение: вернуть как
null
, без каких-либо побочных эффектов. Если вы хотите обновить некоторыеstate
значение состояния, то возвращается объект, который будетstate
модифицировать
Жизненный цикл — это статическая функция, принадлежащая методу класса и не находящаяся в его области видимости.
this
из
render()
render()
Метод является единственным обязательным методом в компоненте класса, а остальную часть жизненного цикла писать не требуется.
Когда компонент визуализируется, он переходит к этому жизненному циклу, а отображаемые компоненты определяются возвращаемым значением жизненного цикла render().
Уведомление:Если метод shouldComponentUpdate() возвращает false, render() вызываться не будет.
componentDidMount()
Вызывается сразу после монтирования компонента React (вставки в дерево).
Жизненный цикл componentDidMount — хорошее время для отправки сетевых запросов и включения прослушивания событий.
При необходимости setState() можно вызвать сразу в этом жизненном цикле.
shouldComponentUpdate(nextProps, nextState)
Вызывается до того, как компонент будет готов к обновлению, вы можете контролировать, обновляется ли компонент, возвращать true, когда компонент обновляется, и возвращать false, когда компонент не обновляется.
Содержит два параметра, первый — это значение реквизита, которое нужно обновить, второй — значение состояния, которое нужно обновить, вы можете судить на основе реквизита или состояния до и после обновления, решить, следует ли обновлять, и выполнить оптимизацию производительности.
не хочу
shouldComponentUpdate
Вызовите setState() в , иначе это вызовет бесконечный цикл вызова обновления и рендеринга, пока память браузера не выйдет из строя.
getSnapshotBeforeUpdate(prevProps, prevState)
getSnapshotBeforeUpdate()
Вызывается перед фиксацией самого последнего вывода рендеринга. То есть после рендера, когда компонент вот-вот будет смонтирован.
Это позволяет компоненту собирать некоторую информацию (например, положение прокрутки) до фактического обновления DOM, любое значение, возвращаемое этим жизненным циклом, передается в качестве параметра в
componentDidUpdate()
. Возвращает null, если не нужно передавать значение
componentDidUpdate(prevProps, prevState, snapshot)
componentDidUpdate()
Вызывается сразу после обновления. Этот жизненный цикл не запускается при первом отображении компонента.
setState() можно вызывать в течение этого жизненного цикла, нодолжен быть включен в условный оператор, в противном случае это вызовет бесконечный цикл и в конечном итоге приведет к сбою памяти браузера.
componentWillUnmount()
componentWillUnmount()
Вызывается, когда компонент собирается быть размонтированным или уничтоженным.
Этот жизненный цикл являетсяотменить сетевой запрос, Удалитьпрослушать событие,Очистить элементы DOM,таймер очисткиОжидание подходящего времени для работы
Уведомление:componentWillMount(), componentWillUpdate(), componentWillReceiveProps() скоро устаревают, пожалуйста, не используйте их в компонентах. Поэтому в этой статье это не объясняется, чтобы избежать путаницы.
порядок выполнения жизненного цикла
при установке
-
constructor()
-
static getDerivedStateFromProps()
-
render()
-
componentDidMount()
При обновлении
-
static getDerivedStateFromProps()
-
shouldComponentUpdate()
-
render()
-
getSnapshotBeforeUpdate()
-
componentDidUpdate()
при удалении
- componentWillUnmount()
Можно ли вызывать setState() в жизненном цикле
инициализировать состояние
- constructor()
можно вызвать setState()
- componentDidMount()
SetState() может быть вызван в соответствии с условием суждения
- componentDidUpdate()
Запретить вызов setState()
-
shouldComponentUpdate()
-
render()
-
getSnapshotBeforeUpdate()
-
componentWillUnmount()
Пример демонстрации
Ниже приводится понимание порядка выполнения каждого жизненного цикла на основе изменения реквизита, изменения состояния родительско-дочернего компонента и монтирования/выгрузки дочерних компонентов.Заинтересованные учащиеся могут посмотреть вместе или загрузить код на испытайте это сами.
написать код компонента
Родительский компонент: Parent.js
import React, { Component } from 'react';
import Child from './Child.js';
const parentStyle = {
padding: 40,
margin: 20,
border: '1px solid pink'
}
const TAG = "Parent 组件:"
export default class Parent extends Component {
constructor(props) {
super(props);
console.log(TAG, 'constructor');
this.state = {
num: 0,
mountChild: true
}
}
static getDerivedStateFromProps(nextProps, prevState) {
console.log(TAG, 'getDerivedStateFromProps');
return null;
}
componentDidMount() {
console.log(TAG, 'componentDidMount');
}
shouldComponentUpdate(nextProps, nextState) {
console.log(TAG, 'shouldComponentUpdate');
return true;
}
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log(TAG, 'getSnapshotBeforeUpdate');
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
console.log(TAG, 'componentDidUpdate');
}
componentWillUnmount() {
console.log(TAG, 'componentWillUnmount');
}
/**
* 修改传给子组件属性 num 的方法
*/
changeNum = () => {
let { num } = this.state;
this.setState({
num: ++ num
});
}
/**
* 切换子组件挂载和卸载的方法
*/
toggleMountChild = () => {
let { mountChild } = this.state;
this.setState({
mountChild: !mountChild
});
}
render() {
console.log(TAG, 'render');
const { num, mountChild } = this.state;
return (
<div style={ parentStyle }>
<div>
<p>父组件</p>
<button onClick={ this.changeNum }>改变传给子组件的属性 num</button>
<br />
<br />
<button onClick={ this.toggleMountChild }>卸载 / 挂载子组件</button>
</div>
{
mountChild ? <Child num={ num } /> : null
}
</div>
)
}
}
Дочерний компонент: Child.js
import React, { Component } from 'react'
const childStyle = {
padding: 20,
margin: 20,
border: '1px solid black'
}
const TAG = 'Child 组件:'
export default class Child extends Component {
constructor(props) {
super(props);
console.log(TAG, 'constructor');
this.state = {
counter: 0
};
}
static getDerivedStateFromProps(nextProps, prevState) {
console.log(TAG, 'getDerivedStateFromProps');
return null;
}
componentDidMount() {
console.log(TAG, 'componentDidMount');
}
shouldComponentUpdate(nextProps, nextState) {
console.log(TAG, 'shouldComponentUpdate');
return true;
}
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log(TAG, 'getSnapshotBeforeUpdate');
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
console.log(TAG, 'componentDidUpdate');
}
componentWillUnmount() {
console.log(TAG, 'componentWillUnmount');
}
changeCounter = () => {
let { counter }= this.state;
this.setState({
counter: ++ counter
});
}
render() {
console.log(TAG, 'render');
const { num } = this.props;
const { counter } = this.state;
return (
<div style={ childStyle }>
<p>子组件</p>
<p>父组件传过来的属性 num : { num }</p>
<p>自身状态 counter : { counter }</p>
<button onClick={ this.changeCounter }>改变自身状态 counter</button>
</div>
)
}
}
Исследуйте порядок выполнения жизненного цикла по времени изменения состояния пяти компонентов.
1. Инициализация родительского и дочернего компонентов
Когда родительско-дочерний компонент визуализируется и загружается в первый раз, интерфейс отображается как:
Порядок печати журнала в консоли:
- Родительский компонент: конструктор()
- Родительский компонент: getDerivedStateFromProps()
- Родительский компонент: рендер()
- Дочерний компонент: конструктор()
- Дочерний компонент: getDerivedStateFromProps()
- Дочерний компонент: рендер()
- Дочерний компонент: componentDidMount()
- Родительский компонент: componentDidMount()
2. При изменении состояния самого дочернего компонента
Щелкните дочерний компонентизменить собственное состояниекнопка, интерфейсСчетчик самоуправления:Значение will + 1, и порядок печати журнала в консоли:
- Дочерний компонент: getDerivedStateFromProps()
- Дочерний компонент: shouldComponentUpdate()
- Дочерний компонент: рендер()
- Дочерний компонент: getSnapshotBeforeUpdate()
- Дочерний компонент: componentDidUpdate()
3. При изменении реквизита, переданного в дочерний компонент в родительском компоненте
Щелкните родительский компонентИзмените номер свойства, переданный дочернему компонентукнопка, интерфейсАтрибут num, переданный от родительского компонента:Значение will + 1, и порядок печати журнала в консоли:
- Родительский компонент: getDerivedStateFromProps()
- Родительский компонент: shouldComponentUpdate()
- Родительский компонент: рендер()
- Дочерний компонент: getDerivedStateFromProps()
- Дочерний компонент: shouldComponentUpdate()
- Дочерний компонент: рендер()
- Дочерний компонент: getSnapshotBeforeUpdate()
- Родительский компонент: getSnapshotBeforeUpdate()
- Дочерний компонент: componentDidUpdate()
- Родительский компонент: componentDidUpdate()
4. Удалить подкомпоненты
Щелкните родительский компонентРазмонтировать/смонтировать подкомпоненткнопки, подкомпоненты в интерфейсе исчезнут, а порядок печати журнала в консоли будет таким:
- Родительский компонент: getDerivedStateFromProps()
- Родительский компонент: shouldComponentUpdate()
- Родительский компонент: рендер()
- Родительский компонент: getSnapshotBeforeUpdate()
- Дочерний компонент: componentWillUnmount()
- Родительский компонент: componentDidUpdate()
5. Перемонтируйте подкомпоненты
Нажмите еще раз в родительском компонентеРазмонтировать/смонтировать подкомпоненткнопка, подкомпоненты в интерфейсе будут перерисованы, а порядок печати журнала в консоли будет следующим:
- Родительский компонент: getDerivedStateFromProps()
- Родительский компонент: shouldComponentUpdate()
- Родительский компонент: рендер()
- Дочерний компонент: конструктор()
- Дочерний компонент: getDerivedStateFromProps()
- Дочерний компонент: рендер()
- Родительский компонент: getSnapshotBeforeUpdate()
- Дочерний компонент: componentDidMount()
- Родительский компонент: componentDidUpdate()
Сводка порядка выполнения жизненного цикла родительско-дочернего компонента:
-
При изменении состояния дочернего компонента родительский компонент не будет обновляться без каких-либо побочных эффектов на родительский компонент, то есть жизненный цикл родительского компонента не будет запущен
-
Когда состояние родительского компонента изменяется (включая монтирование дочернего компонента), это запускает соответствующий жизненный цикл и обновление дочернего компонента.
-
рендеринг и жизненный цикл перед рендерингом, родительский компонент выполняется первым
-
рендер и цикл объявления после рендера, дочерний компонент выполняется первым, и он выполняется поочередно с родительским компонентом
-
-
Когда дочерний компонент размонтирован, будет выполнен только его собственный жизненный цикл componentWillUnmount, и никакие другие жизненные циклы не будут запущены.
Это может быть не очень хорошо и не очень полно. Просто общее резюме. Что-то не так, надеюсь, вы меня поправите.
Загрузка примера кода
Адрес источника(Добро пожаловать, Звезда, спасибо!)
Не видели достаточно? Перейти к:Официальный сайт компонента React