React和Angular的生命周期解析

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后,生命周期函数的执行顺序如下:


修改代码后,生命周期函数的执行顺序如下:


从上述流程,我们可以发现React生命周期如下图所示,主要可以分为三个过程:


图1 “初始版本”的生命周期

 挂载过程(深蓝部分): 该部分包含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,演示结果如下:

由此可见,“更新版本”的生命周期如下图所示:

图2 “更新版本”的生命周期

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”后, 子组件内容展示,此时,生命周期方法的调用顺序为:

点击“Update Hero”后, 子组件内容更新,此时,生命周期方法的调用顺序为:

点击“Destroy PeekABooComponent”后, 子组件消失,此时,生命周期方法的调用顺序为:


基于上述demo,我们可以获知Angular的生命周期可划分为了三个阶段,分别为:组件初始化阶段,变化检测,组件销毁。

 组件初始化阶段:从ngOnChange开始,按照下图的顺序执行,直到ngAfterViewChecked;

 变化检测阶段:主要由ngOnchange、ngDeCheck、ngAfterContentChedked以及ngAfterViewChecked检测;

 组件销毁阶段:由ngOnDestory控制。

值得注意的是,下图紫色的都只会被调用一次,绿色的可被调用多次。

此外,AfterContent 钩子和 AfterView 相似。关键的不同点是子组件的类型不同: AfterContent 所关心的是 ContentChildren,这些子组件被 Angular 投影进该组件中。AfterView 所关心的是 ViewChildren,这些子组件的元素标签会出现在该组件的模板里面。

图3 Angular的生命周期

3、React和Angular生命周期的对比分析

React和Angular的生命周期差异性较大,我尝试在二者生命周期间找到一些共性,下面是我的一些发现,可能不完全匹配,欢迎共同探讨。

4、结语

以上就是我对于React和Angular生命周期的一些理解啦,如果有纰漏或错误,欢迎指出!

又是学习的一天,fighting~

你可能感兴趣的:(React和Angular的生命周期解析)