React基础(六):组件渲染,生命周期详解

引发组件重新渲染的条件:

1,state 状态变化,组件会重新渲染。

2,父组件属性变化,也就是父组件给子组件的 props 发生变化,也会引起重新渲染。

3,强制渲染也可以引起重新渲染。 

在上一篇博客,我们了解了第一种情况,这一篇继续。

首先,我们先写一对父子组件:点击父组件的按钮,改变 a 的值,并给子组件传过去。

首先,在刚出来的时候,会有一次初始渲染。

这个是子组件 render 里面的 console。

扫描二维码关注公众号,回复: 11088049 查看本文章

然后当按钮被点击的时候,你可以看到,子组件的数字确实会变,变的同时右边的控制台也一直在输出“渲染了”。

这个就属于上面的第二种情况,props 发生改变的时候,也会重新渲染。

第三种,就是强制渲染。这个没啥要求,只要你需要,都可以让它强制更新渲染。

force 就是强制的意思,update 是更新的意思。

forceUpdate 它是属于,完全重新的把这个组件给渲染一遍。

说白了,就是不管你到底有没有更新的必要,我就是要你更新。

但是我们一般都不会去用,也不推荐。

因为 render 之所以不是时刻都在执行,目的就是为了节约资源。而在没什么特别的理由前提下,我们是没必要去瞎更新的,这样会打乱 React 自身的渲染计划,也会导致性能的下降,所以极少使用。

接下来我们就来说下组件的生命周期钩子函数。

钩子函数其实很类似于我们平常所说的事件,比如我给页面加个事件 window.onload = function(){ ... },就是当页面加载完成的时候,你要执行这个回调函数。

钩子函数也是如此,它要的是在发生某种事情的时候,你要去调我的这个函数,这就是钩子函数。

钩子函数是存在在每一个组件当中的,那么我们一起来看看它到底怎么用。

首先,它分成三个大的阶段:

1,创建阶段 Mount。原来没有这个组件,现在给它创建出来了。

2,更新阶段 Update。比如说状态发生变化,props 发生变化,或者做了强制渲染,都会导致更新的发生。

3,卸载,销毁的阶段 Unmount。

创建和卸载都是一瞬间的事,基本上来说,存在时间最久的还是更新。

实际开发中,生命周期钩子函数中 componentDidMount 和 componentDidUpdate 用的最多。

那么接下来,就让我们一起来看下这些钩子函数:

首先,我们先来一个简单的组件,看下最先开始的创建。

创建阶段 Mount:

1,先执行 constructor。

不管你是不是一个组件,不管要进行什么工作,首先你是一个类,那么就得遵循类最基本的要求,所以它会最先得到执行。因为如果没有它的话,这个类根本就创建不出来。所以这时还不算是个组件,只是 class 自身的初始化。

2,getDerivedStateFromProps:检查需要更新的状态。

简单来说,它并不是一个生命周期钩子函数,而是一个检查函数,它的作用就是检查更新。它需要检查一下你的状态变没变,然后你哪些状态变了,哪些没变。所以一般我们是不去碰它的,知道有这么个操作就行。

3,执行第一次的 render:初始渲染。

4,触发钩子函数 componentDidMount:组件创建完成,并且已经成功的挂载到 DOM 结构中。(对组件做一些初始化的操作,获取数据)

然后我们在来看下更新的操作:

点击按钮,改变状态 a 的值,自加一。

然后我们添加 shouldComponentUpdate 之后再来看看:

shouldComponentUpdate 有两个参数 nextProps,nextState。就是接下来如果重新渲染了,会变成什么样的属性和状态。并且 shouldComponentUpdate 的返回值决定是否更新。

我们设置下次状态里面 a 的值,如果 %3 为 0 的时候,就更新。说白了就是每三次更新一次。

可以看到,前 2 次点击按钮的时候,a 的值都是 0,第 3 次点击的时候,a 的值才变成 3。

更新阶段 Update:

1,getDerivedStateFromProps:检查需要更新的状态。

首先在更新的时候,如果它是无脑更新所有的东西,那么 React 的性能就会非常的差,所以它的第一步也是 getDerivedStateFromProps。它的作用是检查 state,props 有没有更新,以及哪些更新了,哪些没更新,它需要去检查这些东西。

2,shouldComponentUpdate:即将开始更新组件,可以阻止更新发生。

这个组件应不应该更新,到目前为止还是个问号,它在这里需要去确定这个组件是否应该更新。在某些特殊的情况下,我们可以去阻止它的更新。就比如你打游戏拿 5 杀的时候,突然一个弹框告诉你 windows 要升级了,它是用来询问你的,可升可不升。

所以 shouldComponentUpdate 可以帮助我们去拒绝一些没有意义的更新。一般来说,shouldComponentUpdate 在小的组件里面用不上,但是对于一些大的组件,尤其是有数据交互东西,就非常的有用,它可以根据条件来更新,防止一些死循环。

3,render:如果应该更新,才更新。

这里需要注意的是,render 更新的仅仅是虚拟 DOM,真实的 DOM 还没更新。所以它需要在 getSnapshotBeforeUpdate 中抓住机会,它需要去把 DOM 元素中的状态给做一个保留。

4,getSnapshotBeforeUpdate:从 DOM 中获取状态,已保证更新前后状态一致。

getSnapshotBeforeUpdate 翻译过来就是,在更新之前它要去获取一个快照。它其实是在正式的更新之前,它需要去保存一些 DOM 的状态,比如现在这个滚动条滚到哪个位置了,用户输入了哪些东西,其他东西都是怎么设置的,在哪个位置等等,让这些东西都得到一个保留。保留完了之后,等将来这个 DOM 元素更新了之后,它还要在恢复这个现场。这就是为什么在 React 里面,它能够自动的去维护滚动状态的原因。

5,更新真正的 DOM 元素。

6,componentDidUpdate:更新完之后,会触发钩子函数。这时组件已经渲染完成。(尽量避免在 componentDidUpdate 中更新 state,不然容易造成死循环)

最后我们再来看看销毁:点击按钮,显示隐藏子组件。

销毁阶段 Unmount:

1,componentWillUnmount:组件销毁,销毁操作无法阻止。这个基本也用不上。

componentWillUnmount 不保证一定发生。比如用户直接把浏览器关了,更极端点,用户重启,关机,或者干脆主机炸了,这时候根本就来不及发生 componentWillUnmount。所以为了数据的安全着想,不要把任何的数据操作往它里面放。

发布了78 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43921436/article/details/104210982