React和Angular都具有生命周期,他们的生命周期分别时什么样的?二者生命周期间又有没有什么共同点呢,我们可以一起探讨一下。
1、React的生命周期
React的生命周期主要分为两个版本(以16.4版本划分),为了更好理解,我们将两个版本分为“初始版本”和“更新版本”。下面我们将首先介绍React “初始版本”的生命周期。
1.1 React “初始版本”的生命周期。
React “初始版本”的生命周期方法主要有以下几种,他们的简要定义如下:
constructor:完成了React数据的初始化
componentWillMount:在挂载之前被调用。它在 render() 之前调用,因此在此方法中同步调用 setState() 不会触发额外渲染。
componentDidMount:会在组件挂载后(插入 DOM 树中)立即调用。依赖于 DOM 节点的初始化应该放在这里。返回数据setState后组件会重新渲染
shouldComponentUpdate(nextProps,nextState):当 props 或 state 发生变化时,shouldComponentUpdate会在渲染执行之前被调用。返回值默认为 true。首次渲染或使用forceUpdate时不会调用该方法。如果shouldComponentUpdate返回false,则不会调用componentWillUpdate,render和componentDidUpdate。
componentWillUpdate (nextProps,nextState):当组件收到新的props或state时,且shouldComponentUpdate返回true,会在渲染之前调用该方法。使用此作为在更新发生之前执行准备更新的机会。初始渲染不会调用此方法。
componentDidUpdate(prevProps,prevState):会在更新后会被立即调用。首次渲染不会执行此方法。
render: 会插入jsx生成的dom结构,生成一份虚拟dom树,在每一次组件更新时,react会比较更新前后的新旧DOM树,然后找到最小的有差异的DOM节点,进行重新渲染。
componentWillReceiveProps:会在已挂载的组件接收新的props之前被调用。如果你需要更新状态以响应prop更改(例如,重置它),你可以比较this.props和nextProps,将nextProps的state为当前组件的state,从而重新渲染组件.
componentWillUnmount:会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除timer,取消网络请求或清除在componentDidMount中创建的订阅等。
为了更好理解下面将结合demo,进行查看,实例demo链接如下:
https://codesandbox.io/s/nostalgic-fermat-8t67h?file=/src/App.js
结合代码,我们可以查看生命周期函数的执行顺序。
当页面初始渲染时,我们可以发现生命周期函数的执行顺序如下:
通过“点击+1”更新state后,生命周期函数的执行顺序如下:
修改代码后,生命周期函数的执行顺序如下:
<button onClick={this.handleClick}>点击加1!</button>
从上述流程,我们可以发现React生命周期如下图所示,主要可以分为三个过程:
挂载过程(深蓝部分): 该部分包含constract(初始化)、 componentWillMount、 render、componentDidMount。
更新过程(浅蓝色部分): 该部分包括componentWillReceiveProps(该方法在demo中未展示) 、shouldComponentUpdate、 componentWillUpdate、render、componentWillUpdate
销毁阶段(橙色部分):该部分包括componentWillUnmount
1.2 React “更新版本”的生命周期
React16.4后使用了新的生命周期,具体使用getDerivedStateFromProps代替了旧的componentWillReceiveProps及componentWillMount。使用getSnapshotBeforeUpdate代替了旧的componentWillUpdate。其余的保持不变。
getDerivedStateFromProps:会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回null则不更新任何内容。
getSnapshotBeforeUpdate:该方法会在 render 之后, DOM 更新前被调用,用于读取最新的 DOM 数据。此生命周期方法的任何返回值将作为 componentDidUpdate的第三个参数。
基于上述内容,更改演示demo,演示结果如下:
由此可见,“更新版本”的生命周期如下图所示:
1.3 React hooks的“生命周期”
React在16.8后引入了hooks,让我们可以在不便携class的情况下使用state以及其他的react特性。hooks相比与 class 的生命周期概念来说,它更接近于实现状态同步,而不是响应生命周期事件。我们可以利用useState、useMemo、useEffect、useLayoutEffect来模拟实现生命周期,对应关系如下:
2、Angular的生命周期
Anuglar组件的生命周期钩子方法有以下八种,他们的用途和时机分别如下:
为了更好理解Angular的生命周期方法,下面我们将结合demo进行查看,
demo(下载范例)包含几个示例,其中“Peek-A-Boo”展示每个生命周期方法,每个方法调用后都会在屏幕上显示一条日志。
最开始,页面为下图所示:
点击“Create PeekABooComponent”后, 子组件<peek-a-boo>内容展示,此时,生命周期方法的调用顺序为:
点击“Update Hero”后, 子组件<peek-a-boo>内容更新,此时,生命周期方法的调用顺序为:
点击“Destroy PeekABooComponent”后, 子组件<peek-a-boo>消失,此时,生命周期方法的调用顺序为:
基于上述demo,我们可以获知Angular的生命周期可划分为了三个阶段,分别为:组件初始化阶段,变化检测,组件销毁。
组件初始化阶段:从ngOnChange开始,按照下图的顺序执行,直到ngAfterViewChecked;
变化检测阶段:主要由ngOnchange、ngDeCheck、ngAfterContentChedked以及ngAfterViewChecked检测;
组件销毁阶段:由ngOnDestory控制。
值得注意的是,下图紫色的都只会被调用一次,绿色的可被调用多次。
此外,AfterContent 钩子和 AfterView 相似。关键的不同点是子组件的类型不同: AfterContent 所关心的是 ContentChildren,这些子组件被 Angular 投影进该组件中。AfterView 所关心的是 ViewChildren,这些子组件的元素标签会出现在该组件的模板里面。
3、React和Angular生命周期的对比分析
React和Angular的生命周期差异性较大,我尝试在二者生命周期间找到一些共性,下面是我的一些发现,可能不完全匹配,欢迎共同探讨。
4、结语
以上就是我对于React和Angular生命周期的一些理解啦,如果有纰漏或错误,欢迎指出!
又是学习的一天,fighting~