предисловие
Если компонент сравнивается с 🐜 на нашем рисунке, праща сравнивается с жизнью 🐜 (компонента), левый конец пращи представляет рождение 🐜 (создание компонента), а правый конец представляет собой смерть 🐜 (уничтожение компонента). 🐜 Процесс от рождения до смерти вызовет выполнение функции хука на теге.
ReactФункцию хука, которая должна срабатывать в процессе создания компонента на уничтожение, мы называем функцией жизненного цикла.
ReactЖизненный цикл
старая версия
фаза инициализации (Initalization)
-
setup props ande state(Установите свойства инициализации и состояние компонента)
Инициализировать объект состояния
static defaultProps = {
name:'计数器' //初始化默认的属性对象
}
Инициализация атрибута объекта
constructor(props){
super(props);
this.state = {
number:0
}
}
монтажный этап (Mounting)
Монтаж: процесс преобразования виртуального DOM в настоящий DOM.
componentWillMount
Прежде чем компонент будет смонтирован, он может выполняться несколько раз в процессе рендеринга, что не рекомендуется.
render
крепление компонента
componentDidMount
После того, как компонент будет смонтирован, он будет выполнен только один раз, на этом этапе рекомендуется выполнять побочные эффекты и асинхронные операции. такие как волосы
ajaxзапрос, действиеDOMЖдать
этап обновления (Updation)
Обновление свойства (изменение реквизита)
componentWillReceiveProps
Вызывается, когда компонент получает новый объект свойства, первый рендеринг не будет запускаться
shouldComponentUpdate
Спросите, можно ли обновить компонент
- Параметры: новый объект свойств
- вернуть:
booleanстоимость-
trueРазрешить продолжение обновления -
falseОбновления запрещены, выполнение остановлено, а последующие функции жизненного цикла вызываться не будут.
-
componentWillUpdate
До обновления компонента
render
Перемонтировать (рендерить) компонент на основе нового объекта свойства
componentDidUpdate
Обновление компонента завершено
обновление состояния (изменение состояния)
shouldComponentUpdate
Спросите, можно ли обновить компонент
- Параметры: новый объект состояния
- вернуть:
booleanстоимость-
trueРазрешить продолжение обновления -
falseОбновления запрещены, выполнение остановлено, а последующие функции жизненного цикла вызываться не будут.
-
componentWillUpdate
До обновления компонента
render
Перемонтировать (рендерить) компонент на основе нового объекта состояния
componentDilUpdtae
Обновление компонента завершено
Удалить фазу (Unmounting)
componentWillUnmount
Вызывается перед выгрузкой компонента
Оценка более
Заинтересованные друзья могут протестировать в соответствии со следующим кодом
import React, { Component } from 'react';
/**
* 父组件
*/
class Counter extends Component {
static defaultProps = { //初始化默认的属性对象
name:'计数器'
}
constructor(props) {
super(props);
this.state = { // 初始化默认的状态对象
number:0
}
console.log('1. 父constructor初始化 props and state');
}
componentWillMount() {
console.log('2. 父componentWillMount组件将要挂载');
}
componentDidMount() {
console.log('4. 父componentDidMount组件挂载完成');
}
shouldComponentUpdate() {
console.log('5. 父componentShouldUpdate询问组件是否可以更新');
return true;
}
componentWillUpdate() {
console.log('6. 父componentWillUpdate组件将要更新');
}
componentDidUpdate() {
console.log('7. 父componentDidUpdate组件更新完成');
}
render() {
console.log('3. 父render渲染,也就是挂载');
const style = {display:'block'}
return (
<div style={{border:'10px solid green',pending:'10px'}}>
{this.props.name}:{this.state.number}
<button onClick={this.add} style={style}>+</button>
{this.state.number %3 !== 0 && <SubCounter number={this.state.number}/>}
</div>
);
}
add = () => {
this.setState({
number:this.state.number+1
})
}
}
/**
* 子组件
*/
class SubCounter extends Component {
static defaultProps = {
number:10
}
componentWillReceiveProps() {
console.log('1. 子componentWillReceiveProps属性将要发生变化 ');
}
shouldComponentUpdate(nextProps, nextState) {
console.log('2. 子componentShouldUpdate询问组件是否可以更新');
// 调用此方法的时候会把新的属性对象和新的状态对象传递过来
if (nextProps.number % 3 === 0) {
return true;
}
return false;
}
componentWillUnmount() {
console.log(' 3.子componentWillUnmount组件将要卸载 ');
}
render() {
return (
<div style={{border:'10px solid red'}}>
{this.props.number}
</div>
);
}
}
export default Counter;
новая версия
при создании
constructor
Инициализировать свойства и состояние
getDerivedStateFromProps
Получить объект состояния из объекта свойства
- статический метод
- Параметры: новый объект свойства, старый объект состояния
- Цель: до этой функции жизненного цикла источником данных, который мы используем, могут быть объекты атрибутов или объекты состояния.Оценка болееСтадия отражена, мы можем вывести объект атрибута в объект состояния через эту функцию жизненного цикла, так что мы можем только передать
this.state.XXXчтобы связать наши данные. Примеры следующие
import React, { Component } from 'react';
/**
* 父
*/
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
number:0
}
}
render() {
return (
<div>
<p>{this.state.number}</p>
<button onClick={this.add}>+</button>
<SubCounter number={this.state.number}/>
</div>
);
}
add = () => {
this.setState({
number:this.state.number+1
})
}
}
/**
* 子
*/
class SubCounter extends Component {
constructor(props) {
super(props);
this.state = {
number:0
}
}
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.number % 2 === 0) {
return {number:nextProps.number*2}
} else {
return {number:nextProps.number*3}
}
}
render() {
console.log(this.state);
return (
<div>
<p>{this.state.number}</p>
</div>
);
}
}
export default Counter;
render
Монтировать (рендерить) компоненты
componentDidMount
Монтаж компонента (рендеринг) завершен
При обновлении
getDerivedStateFromProps
Получить объект состояния из объекта свойства
- статический метод
- Параметры: новый объект свойства, старый объект состояния
shouldComponentUpdate
Спросите, можно ли обновить компонент
- Параметры: новый объект состояния
- вернуть:
booleanстоимость-
trueРазрешить продолжение обновления -
falseОбновления запрещены, выполнение остановлено, а последующие функции жизненного цикла вызываться не будут.
-
render
Перемонтировать (рендерить) компонент на основе нового объекта состояния
getSnapshotbeforeUpdate
Получите снимок перед обновлением
- Например: в нашей ежедневной разработке вы обязательно столкнетесь с этой проблемой Загрузка ресурсов асинхронно Когда браузер не на первом экране и модуль перед экраном не загружен, в экране точно не хочется. После загрузки модуля окно отображения браузера все еще находится на текущей высоте, но есть надежда, что оно все еще находится на высоте просматриваемого нами экрана, прежде чем такого жизненного цикла не будет.
reactСправиться с этой проблемой непросто.
Неиспользованный
getSnapshotbeforeUpdate
import React, { Component } from 'react';
class GetSnapshotBeforeUpdate extends Component {
constructor(props) {
super(props);
this.wrapper = React.createRef();
this.state = {
messages:['4','3','2','1','0']
}
}
componentDidMount() {
setInterval(() => {
this.setState(() => {
this.state.messages.unshift(this.state.messages.length);
}, () => {
this.setState({
messages: this.state.messages
})
})
},1000)
}
render() {
let style = {
height: '100px',
width: '200px',
border: '1px solid red',
overflow:'auto'
}
return (
<ul style={style} ref={this.wrapper}>
{
this.state.messages.map((message, index) => <li key={index}>{message}</li>)
}
</ul>
);
}
}
export default GetSnapshotBeforeUpdate;
использовать
getSnapshotbeforeUpdate
import React, { Component } from 'react';
class GetSnapshotBeforeUpdate extends Component {
...
getSnapshotBeforeUpdate() {
// 返回更新内容的高度
return this.wrapper.current.scrollHeight;
}
// 组件更新完毕
componentDidUpdate(prevProps,prevState,prevScrollHeight) {
console.log(prevProps,prevState,prevScrollHeight);
this.wrapper.current.scrollTop = this.wrapper.current.scrollTop +
(this.wrapper.current.scrollHeight - prevScrollHeight);
}
...
export default GetSnapshotBeforeUpdate;
componentDidUpdate
Обновление компонента завершено
при удалении
componentWillUnmount
Перед удалением компонентов
Суммировать
Почему сбор данных должен быть вcomponentDidMountвнутренний вызов
-
constructorсередина-
constructor()Если это займет слишком много времени или произойдет ошибка, компонент не будет отображаться, и вся страница не будет отображаться.
-
-
componentWillMount()-
【1】При использовании
SSR(рендеринг на стороне сервера),componentWillMountОн будет выполнен дважды, один раз на сервере и один раз на клиенте. А componentDidMount — нет. -
【2】
React16позже принятоFiberтолько архитектураcomponentDidMountОбъявляет, что периодическая функция обязательно выполняется один раз, аналогичноcomponentWillMountЛовушки жизненного цикла могут выполняться несколько раз, поэтому не выполняйте побочные операции в этих жизненных циклах, такие как запрос данных.
-
-
componentDidMount()-
[1] Убедитесь, что у вас есть
renderоднажды. Напоминает нам правильно установить начальное состояние, чтобы мы не получали ошибок, вызывающих ошибкиundefinedусловие. -
【2】
componentDidMountКод в методе вызывается и выполняется после того, как компонент полностью смонтирован на веб-странице, поэтому загрузка данных может быть гарантирована. Кроме того, вызов метода setState в этом методе вызовет повторную визуализацию. Поэтому этот метод официально разработан для загрузки внешних данных или обработки других кодов побочных эффектов.
-
Сравнение старого и нового (отходы три плюс два)
- заброшенный
componentWillMountcomponentWillReceivePropscomponentWillUpdate
- повысился
getDerivedStateFromPropsgetSnapshotbeforeUpdate