React17 生命周期


在这里插入图片描述


在17版本中

  • 废除的生命周期有:componentWillMountcomponentwillReceivePropscomponentWillUpdate
  • 新增的生命周期有:getDerivedStateFromProps(nextProps, prevState)

.

生命周期顺序

Mounting 挂载顺序(初始化)

  1. constructor(props):初始化 state 和 props 数据
  2. 新增 static getDerivedStateFromProps(nextProps, prevState):组件初始化和被更新时调用
    用来替代 componentWillMount() 在组件即将被挂载到页面时执行(16.3已废弃)
  3. render():渲染组件
  4. componentDidMount():在组件被挂载到页面后执行,只在挂载时执行一次

Updation 更新顺序(更新)

  1. static getDerivedStateFromProps(nextProps, prevState):组件初始化和被更新时调用
  2. shouldComponentUpdate(nextProps, nextState):在组件被更新之前执行 (return true 更新 , return false 不更新)
  3. render(): 渲染页面
  4. static getSnapshotBeforeUpdate(prevProps, prevState)
  5. componentDidUpdate():state或props更新后调用

Unmounting 卸载(销毁)

  1. componentWillUnmount():在组件即将被页面剔除时执行

注意

除了render函数,其他所有的生命周期函数都可以没有


生命周期详解

1. constuctor

初始化 state 和 props 数据:

  1. 组件的初始化,用来定义当前组件所需要的一些状态,状态定义在 this.state 中;
  2. 当前生命周期中必须书写 super,否则 this 的指向会发生错误以及报错;
  3. 在当前生命周期中默认是访问不到 props 属性的,如果想要进行访问必须在 super 以及 constructor 中添加参数 props
import { Component } from 'react';
import store from './store/index';

class List extends Component {
    constructor(props) {
        super(props);
        this.state = store.getState();
        store.subscribe(this.storeChange.bind(this)); // store发生改变时,自动触发
    }
    storeChange() {
        this.setState(store.getState());
    }
}

2. componentWillMount(废弃)

组件即将被挂载到页面前:

  1. 可以进行前后端数据的请求(在服务端渲染的时候)
  2. 可以在数据第一次被渲染的时候做数据的更改
  3. 在当前生命周期中尽量不要调用 this.setState 因为当前生命周期函数执行完毕后,会自动执行 render 函数
  4. 可以将外部的数据转换为内部的数据

3. static getDerivedStateFromProps(新增)

  1. static getDerivedStateFromProps(nextProps,prevState):接收父组件传递过来的 props 和组件之前的状态,返回一个对象来更新 state 或者返回 null 来表示接收到的 props 没有变化,不需要更新 state ;
  2. 该生命周期钩子的作用: 将父组件传递过来的 props 映射 到子组件的 state 上面,这样组件内部就不用再通过 this.props.xxx 获取属性值了,统一通过 this.state.xxx 获取。映射就相当于拷贝了一份父组件传过来的 props ,作为子组件自己的状态。注意:子组件通过 setState 更新自身状态时,不会改变父组件的 props
  3. 配合 componentDidUpdate,可以覆盖 componentWillReceiveProps 的所有用法;

注意:

  1. getDerivedStateFromProps前面要加上static保留字,声明为静态方法,不然会被react忽略掉
  2. getDerivedStateFromProps里面的 thisundefined.

4. render

  1. 当前生命周期用来进行数据与模板的结合
  2. render 函数第一次执行的时候会将渲染的数据在内存中保存一份,当第二次数据发生了改变后,render 会将这次的虚拟DOM与缓存中的虚拟DOM进行对比(diff 算法)
  3. 只要 this.statethis.props 发生了改变那么 render 函数就会执行
render() {
    return (
		<input id="input" type="text" value={this.state.value} onChange={this.change.bind(this)} />
    );
}

5. componentDidMount

在组件被挂载到页面后执行,只在挂载时执行一次:

  1. 当前生命周期我们可以做前后端数据的交互

  2. 可以在当前生命周期中获取到真实的DOM 通过 this.refs 来获取

  3. 一般情况下我们都在当前生命周期中做一些插件的实例化


版本迁移

  • componentWillMountcomponentWillReceivePropscomponentWillUpdate 这三个生命周期因为经常会被误解和滥用,所以被称为 不安全的生命周期(不是指安全性,而是表示使用这些生命周期的代码,有可能在未来的 React 版本中存在缺陷,可能会影响未来的异步渲染)

  • React 16.3 版本:为不安全的生命周期引入别名 UNSAFE_componentWillMountUNSAFE_componentWillReceivePropsUNSAFE_componentWillUpdate。(旧的生命周期名称和新的别名都可以在此版本中使用

  • React 16.3 之后的版本:为 componentWillMountcomponentWillReceivePropscomponentWillUpdate 启用弃用警告。(旧的生命周期名称和新的别名都可以在此版本中使用,但旧名称会记录DEV模式警告)

  • React 17.0 版本: 推出新的渲染方式——异步渲染( Async Rendering ),提出一种可被打断的生命周期,而可以被打断的阶段正是实际 dom 挂载之前的虚拟 dom 构建阶段,也就是要正式废弃三个生命周期 componentWillMountcomponentWillReceivePropscomponentWillUpdate。(从这个版本开始,只有新的“UNSAFE_”生命周期名称将起作用)


import { Component } from 'react';

export default class LifeCycle extends Component {
    constructor(props) {
        super(props);
        this.state = { number: 0 }; // 初始化默认的状态对象
        console.log('1. constructor 初始化props和state');
    }

    // componentWillMount() {
    //     console.log('2. componentWillMount 组件将要挂载');
    // }

    static getDerivedStateFromProps(nextProps, prevState) {
        console.log('2. getDerivedStateFromProps');
        const { list } = nextProps;
        // 当传入的list发生变化的时候,更新state
        if (list !== prevState.list) {
            return {
                list,
            };
        }
        // 否则,对于state不进行任何操作
        return null;
    }

    render() {
        console.log('3. render 渲染');
        return (
            <div>
                <p>{this.state.number}</p>
                <button onClick={this.add}>+</button>
            </div>
        );
    }

    componentDidMount() {
        console.log('4. componentDidMount 组件挂载完成');
    }

    shouldComponentUpdate(nextProps, nextState) {
        console.log('5. shouldComponentUpdate 询问组件是否需要更新');
        return true;
    }

    // componentWillUpdate() {
    //     console.log('6. componentWillUpdate 组件将要更新');
    // }

    componentDidUpdate() {
        console.log('6. componentDidUpdate 组件更新完毕');
    }

    add = () => {
        this.setState({ number: this.state.number + 1 });
    };
}
posted @ 2021-11-08 11:08  猫老板的豆  阅读(258)  评论(0编辑  收藏  举报