Жизненный цикл реакции

опрос

предисловие

Если компонент сравнивается с 🐜 на нашем рисунке, праща сравнивается с жизнью 🐜 (компонента), левый конец пращи представляет рождение 🐜 (создание компонента), а правый конец представляет собой смерть 🐜 (уничтожение компонента). 🐜 Процесс от рождения до смерти вызовет выполнение функции хука на теге.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 в этом методе вызовет повторную визуализацию. Поэтому этот метод официально разработан для загрузки внешних данных или обработки других кодов побочных эффектов.

Сравнение старого и нового (отходы три плюс два)

  • заброшенный
    • componentWillMount
    • componentWillReceiveProps
    • componentWillUpdate
  • повысился
    • getDerivedStateFromProps
    • getSnapshotbeforeUpdate