React高级(六)

一. React 生命周期

在这里插入图片描述
通过这张图你可以看到React生命周期的四个大阶段:

  1. Initialization:初始化阶段。
  2. Mounting: 挂载阶段。
  3. Updation: 更新阶段。
  4. Unmounting: 销毁阶段

在这里插入图片描述

什么是生命周期函数

如果非要用一句话把生命周期函数说明白,我觉的可以用这句话来说明:

生命周期函数指在某一个时刻组件会自动调用执行的函数

1.1 Initialization阶段

我们可以把构造函数里的这个阶段叫做Initilization阶段,包括定义属性(props)和状态(state)。

constructor(props) {
    super(props);
    this.state = {
        inputValue: '',
        list: ['aaaa', 'bbbb', 'cccc']
    }
}
1.2 Mounting阶段

Mounting阶段即挂载阶段,伴随着整个虚拟DOM的生成,它里边有三个小的生命周期函数,分别是:

  1. componentWillMount : 在组件即将被挂载到页面的时刻执行。
  2. render : 页面state或props发生变化时执行。
  3. componentDidMount : 组件挂载完成时被执行。
    //生命周期函数测试
    UNSAFE_componentWillMount() {
        console.log('componentWillMount')
    }
    componentDidMount() {
        console.log('componentDidMount')
    }

注意的问题:

  1. componentWillMountcomponentDidMount这两个生命周期函数,只在页面刷新时执行一次,而render函数是只要有state和props变化就会执行,这个初学者一定要注意。
  2. componentWillMount在React的V16.9版本中进行了升级,推荐使用UNSAFE_componentWillMount来代替componentWillMount。 参考如下速读 | 了解 React v16.9 最新特性

二. React生命周期中的Updation阶段

React生命周期中的Updation阶段,也就是组件发生改变的更新阶段,这是React生命周期中比较复杂的一部分,它有两个基本部分组成,一个是props属性改变,一个是state状态改变(这个在生命周期的图片中可以清楚的看到)。

2.1 shouldComponentUpdate函数

shouldComponentUpdate函数会在组件更新之前,自动被执行。比如写入下面的代码:

shouldComponentUpdate(){
    console.log('shouldComponentUpdate---组件发生改变前执行')
}

它要求返回一个布尔类型的结果,必须有返回值,这里就直接返回一个true了(真实开发中,这个是有大作用的)。

shouldComponentUpdate(){
    console.log('shouldComponentUpdate---组件发生改变前执行')
    return true
}

现在就可以在控制台console里看到结果了,并且结果是每次文本框发生改变时都会随着改变。如果你返回了false,这组件就不会进行更新了。 简单点说,就是返回true,就同意组件更新;返回false,就反对组件更新。

2.2 componentWillUpdate函数

componentWillUpdate在组件更新之前,但shouldComponenUpdate之后被执行。但是如果shouldComponentUpdate返回false,这个函数就不会被执行了。

//shouldComponentUpdate返回true才会被执行。
componentWillUpdate(){
    console.log('componentWillUpdate---组件更新前,shouldComponentUpdate函数之后执行')
}
2.3 componentDidUpdate

componentDidUpdate在组件更新之后执行,它是组件更新的最后一个环节。

componentDidUpdate(){
    console.log('componentDidUpdate----组件更新之后执行')
}

为了方便我们看出结果,可以在每个函数前加上序号。最后我们可以看到控制台输出的结果如下:

1-shouldComponentUpdate---组件发生改变前执行
2-componentWillUpdate---组件更新前,shouldComponentUpdate函数之后执行
3-render----开始挂载渲染
4-componentDidUpdate----组件更新之后执行
2.4 componentWillReceiveProps 函数

我们可以先在Xiaojiejie.js组件里写下这个函数,例如下面的代码。

componentWillReceiveProps(){
    console.log('componentWillReceiveProps')
}

这时候会发现函数什么时候都不会被执行,因为Xiaojiejie.js算是一个顶层组件,它并没接收任何的props。可以把这个函数移动到XiaojiejieItem.js组件中。

凡是组件都有生命周期函数,所以子组件也是有的,并且子组件接收了props,这时候函数就可以被执行了。

componentWillReceiveProps(){
        console.log('child - componentWillReceiveProps')
}

这个时候再预览,就会看到componentWillReceiveProps执行了。那现在可以总结一下它的执行时间了:
子组件接收到父组件传递过来的参数,父组件render函数重新被执行,这个生命周期就会被执行。

注意:子组件接收到父组件传递过来的参数,父组件render函数重新被执行,这个生命周期就会被执行。

  • 也就是说这个组件第一次存在于Dom中,函数是不会被执行的;
  • 如果已经存在于Dom中,函数才会被执行。

这个生命周期算是比较复杂的一个生命周期,需要我们花点时间去消化。

2.5 React生命周期中的Unmounting阶段

componentWillUnmount这个生命周期函数是组件DOM中被移除时执行。
比如在XiaojiejieItem.js,写入下面的代码:

//当组件从页面中删除的时候执行
componentWillUnmount(){
    console.log('child - componentWillUnmount')
}

写完后,可以到浏览器终端中查看结果,当我们点击服务项,服务项被删除时,这个函数就被执行了。


备注:

class AutoFocusTextInput extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 1
        };
    }
    render() {
        const { count } = this.state;
        return (
            <div>
                <button onClick={() => this.setState({ count: count + 1 })}>按钮{count}</button>
                <CustomTextInput value={count} />
            </div>
        );
    }
}
class CustomTextInput extends React.Component {
    constructor(props) {
        super(props);
    }
    shouldComponentUpdate(nextProps) {
        console.log('this.props', this.props);
        console.log('nextProps', nextProps);
        return true;
    }

    componentDidUpdate(prevProps) {
        console.log('prevProps', prevProps);
        console.log('props', this.props);
    }
    render() {
        return (
            <div>
            </div>
        );
    }
}

打印结果:

在这里插入图片描述


三. 生命周期改善程序性能

已经对React生命周期有了认识,那如何利用它提高组件的性能呢?下面来说一下通过shouldComponentUpdate函数,改善React组件性能的例子。

3.1 小姐姐组件存在性能问题

是的,小姐姐组件已经写的很熟悉了,但是它有一个性能问题,我一直没告诉你,那就是子组件XiaojiejieItem频繁无用渲染render。如何能看出这个问题的呢?

React Developer Tools中, 找到React标签,然后在右边点开设置,选中highlight Updates。
在这里插入图片描述
这时候你在浏览器的文本框中输入一下内容,你可以清楚的看到子组件也发生了重新render的情况。

有很多程序员会忽略这样的性能损耗,认为没有什么大不了的,但是软件的卡顿是一点点产生的,所以必须要减少性能损耗。

可以在XiaojiejieItem.js的render函数里加入下面的代码,更直观的看到这个问题。

render() { 
    console.log('child-render')
    return ( 
        <div onClick={this.handleClick}>
            {this.props.avname}为你做- {this.props.content}
        </div>
    );
}
3.2 利用shouldComponentUpdate解决

这个问题看似很小,但是当你页面很复杂时,足以影响用户体验,不要骗自己了。其实用shouldComponentUpdate函数就可以简单的解决调这个问题。

直接在XiaojiejieItem.js中加入下面的代码:

shouldComponentUpdate(){
    return false;
}

这时候在浏览器中查看,问题已经没有了。但是这样做太暴力了,否定了所有的东西,那如果在真实项目中,需要改变值属性值,就不能进行渲染了。所以我们可以更优雅一下,写出下面的代码。

shouldComponentUpdate有两个参数:

  • nextProps:变化后的属性;
  • nextState:变化后的状态;
shouldComponentUpdate(nextProps,nextState){
    if(nextProps.content !== this.props.content){
        return true
    }else{
        return false
    } 
}

现在的代码就优雅一些了,也不那么暴力了。这就算是完美解决了子组件的渲染性能问题,你写的代码质量也得到了提高。其实在面试React让写TODOList应用的,都是看这个来区分等级的,能写出来的,这算普通程序员;能写出来并作性能优化的,这算有经验的程序员。

四. 生命周期总结(自己理解)

  1. 生命周期总共有4个阶段。
  2. 在第一次打开浏览器页面的时候,只触发Initiation和Mounting阶段。
  3. 在对页面有变动操作的时候,会触发第三个阶段,即Updating阶段。
  4. 在父组件render之后会执行子组件里的生命周期,包括还是那4个阶段,即又回到了1。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

. . . . .

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

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

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

打赏作者

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

抵扣说明:

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

余额充值