React-学习笔记(4-组件生命周期)

1、旧 的生命周期函数(9个)

 

 

  • 初始化时调用的生命周期函数(初始化由 ReactDOM.render() 引发)

  1. constructor —— 就是类的构造器,最早执行的,一生只执行一次 。
  2. UNSAFE_componentWillMount —— 将要挂载,一生只执行一次。

                旧名称为 componentWillMount ,已经废弃。在未来的某个新版本开始将不再支持旧名称的写法。

  1. render —— 将组件渲染到页面中,将执行至少一次。
  2. componentDidMount —— 组件挂载完毕后执行,常在该函数内做一些初始化的操作。
  • 更新阶段会调用的生命周期函数(由组件内部的数据更新或父组件重新渲染时调用) 

  1. UNSAFE_componentWillReceiveProps —— 当前组件的父组件只要触发 render 重新渲染时,子组件就会调用这个生命周期函数 。

                 旧名称为 componentWillReceiveProps ,已经废弃。在未来的某个新版本开始将不再支持旧名称的写法。

  1. shouldComponentUpdate —— 该函数有一个 boolean 类型的返回值,决定是否进行更新操作。若该函数返回 false,则再不会执行下方的三个函数。

         该函数如果不自行指定的话,默认是返回一个true,继续更新操作的。若自行指定,则需要设定一个 boolean 类型的返回值,如果没有指定返回值,则返回一个 undefined,即 boolean 类型的 false,则不会接着执行更新的操作。

  1. UNSAFE_componentWillUpdate —— 即将更新,还没有更新。

                旧名称为 componentWillUpdate ,已经废弃。在未来的某个新版本开始将不再支持旧名称的写法。

  1. render —— 走到这里,数据已经更新,准备重新渲染组件。
  2. componentDidUpdate —— 数据更新完毕,组件重新渲染完毕。

        会接收到两个参数。分别是:旧的 props,旧的 state。(在新版生命周期中,新增了一个 getSnapshotBeforeUpdate 生命周期函数,会返回一个自定义的数据给 componentDidUpdate 作为第三个参数)

  • 卸载组件时调用的声明周期函数(由 ReactDOM.unmountComponentAtNode() 方法触发)

  1. componentWillUnmount —— 即将卸载当前组件,可以执行一下收尾性的工作 。

        下方代码简单演示除 UNSAFE_componentWillReceiveProps 生命周期函数之外所有的生命周期函数的相关内容。

class OldTotalExample extends React.Component{
    // 构造器 组件挂载前调用一次,最早
    constructor(props){
        console.log('constructor');
        super(props);
        this.state = {
            num:0
        }
    }

    // 点击按钮进行自增的函数(自定义函数)
    autoIncrement = ()=>{
        this.setState({
            num:this.state.num + 1
        })
    }

    // 点击按钮将组件卸载 (自定义函数)
    destroyComponent = ()=>{
        // 手动卸载当前组件的函数
        React.unmountComponentAtNode(document.getElementById('test'));
    }

    // 点击按钮强制更新组件 (自定义函数)
    forceRefresh = () =>{
        // 触发重新渲染
        this.forceUpdate();
        // 后续执行顺序 componentWillUpdate -> render -> componentDidUpdate
    }

    // 挂载前调用一次,一生中只调用一次
    UNSAFE_componentWillMount(){
        console.log('componentWillMount');
    }

    // 挂载完调用一次,一生只调用一次
    componentDidMount(){
        console.log('componentDidMount');
    }

    // 是否允许组件内部数据更新 setState 后调用或父组件重新 render 时
    // 需要返回一个 boolean 值以决定是否更新
    // 若该声明周期函数不写,则默认返回true,允许更新
    // 若写该函数,则返回值省略时,返回undefined,即对应boolean值为false,将不再更新
    shouldComponentUpdate(){
        console.log('shouldComponentUpdate');
        return true;
    }

    // 数据将要更新,组件将要重新渲染
    UNSAFE_componentWillUpdate(){
        console.log('componentWillUpdate');
        // 若由组件内部数据更新引起,此时还组件内的数据没有更新
        // 走完这个函数,将走 render 函数
        // 执行 render 前,数据已经更新完毕
        console.log('@',this.state);
    }

    // 组件内部数据更新或父组件重新render后,触发 shouldComponentUpdate ->
    // componentWillUpdate -> render -> componentDidUpdate(当前这个),表示数据和组件已经更新完毕
    // 会接收到两个参数,一个是旧的props,一个是旧的state
    componentDidUpdate(preprops, prestate){
        console.log('componentDidUpdate', preprops, prestate);
    }

    // 组件将要被卸载时调用
    componentWillUnmount(){
        console.log('componentWillUnmount');
    }

    // 组件内部数据更新时或父组件重新render时,该组件的render也重新调用
    render(){
        console.log('render',this.state);
        return (
            <div>
                <h1>current number:{this.state.num}</h1>
                <button onClick={this.autoIncrement}>click me to auto-increment</button><br/>
                <button onClick={this.destroyComponent}>click me to distroy the component</button><br/>
                <button onClick={this.forceRefresh}>click me to force refresh component</button>
            </div>
        )
    }
}

ReactDOM.render(<OldTotalExample/>, document.getElementById('test'));

 

        下方代码演示简单父子组件的使用、演示 UNSAFE_componentWillReceiveProps 生命周期函数相关的内容。

class Father extends React.Component{
    state = {
        currentYear:2023,
        name:'tom',
        age:25,
        gender:'man'
    }
    render(){
        let {currentYear, name, age, gender} = this.state;
        return(
            <div>
                {
                    // 当 currentYear 更新时,子组件也会触发从 componentWillReceiveProps 到
                    // componentDidUpdate 的重新渲染链,这里的 currentYear 不是子组件所依赖的数据
                }
                <h1>{currentYear}</h1>
                {
                    // 在父组件中使用子组件
                }
                <Children name={name} age={age} gender={gender}/>
                <button onClick={()=>{this.setState({age:age + 1})}}>lick to add age</button>
                <button onClick={()=>{this.setState({currentYear:currentYear + 1})}}>click into new year</button>
            </div>
        )
    }
}

// 子组件也是继承于 React.Component
class Children extends React.Component{
    /*
        只要是父组件重新render了,子组件这个生命周期函数以及
        shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate
        都会被接连调用(顺序即以上排列的顺序)
        不管是不是子组件所依赖于父组件的 props 值被更新
    */
    UNSAFE_componentWillReceiveProps(props){
        // 已经接收到'新'的 props 了,
        console.log(props);
    }

    render(){
        return (
            <div>
                <h2>name: {this.props.name}</h2>
                <h2>age: {this.props.age}</h2>    
                <h2>gender: {this.props.gender}</h2>    
            </div>
        )
    }
}

ReactDOM.render(<Father/>, document.getElementById('test'));

2、新 生命周期函数(9 - 3 + 2 = 8)

 

 

        以下三个旧的生命周期函数不建议再去使用:

  • UNSAFE_componentWillMount
  • UNSAFE_componentWillUpdate
  • UNSAFE_componentWillReceiveProps

        新增了两个生命周期函数(实际使用的频率都比较低):

  • statis getDerivedStateFromProps(props, state)

        如果该组件是单纯由 props 决定数据渲染的或状态依赖于 props ,则可以使用到该静态方法。

        该方法接收到两个参数,一个是props,一个是当前组件的state。

        如果定义了静态 getDerivedStateFromProps, React将在调用render之前调用它,无论是在初始挂载时还是在后续更新时。

        它应该返回一个对象来更新状态,或者返回null来表示不更新任何东西。

 

  • getSnapshotBeforeUpdate(preProps, preState)

        当组件即将要渲染到页面上时,将调用该方法。

        该方法接收到两个参数,一个是旧的props,一个是当前组件旧的 state。

        如使用该方法,则必须要返回一个快照值(snapshot)。可以是任何类型的数据,如数值、字符串、对象等,也可以是null,但不能是undefined。该快照值将作为执行 componentDidUpdate的第三个参数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bodyHealthy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值