[React] 多组件生命周期转换关系
前段时间一直在基于React做开发,最近得空做一些总结,防止以后踩坑。
言归正传,React生命周期是React组件运行的基础,本文主要是归纳多组件平行、嵌套时,生命周期转换关系。
生命周期
React生命周期中有如下几种转换方式:
类调用:
此过程仅在类创建时被一次,即无论创建多少个ReactElement,此过程均只会执行一次
- getDefaultProps
实例化:
此过程仅执行一次,执行完毕后,React组件真正被渲染到DOM中
期间执行生命周期函数如下:
- getInitialState
- componentWillMount
- render
- componentDidMount
变更:
此过程会在this.state或this.props变更时执行
期间执行生命周期函数如下:
- this.state变更
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
- this.props变更
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
卸载:
此过程在组件销毁前调用一次
期间执行生命周期函数如下:
- componentWillUnmount
整个生命周期所涉及的方法如图所示:

测试多组件生命周期转换
以上描述了单个组件内部生命周期转换过程,但实际开发中,组件往往存在着平行或嵌套的关系,这时候,只了解单个组件的运行过程是不够的,下面通过不同场景,归纳多组件生命周期的转换关系。
测试demo如下(github:https://github.com/hhhyaaon/react-lifecycle-demo):

- 父组件Component_Super,子组件Component_Sub_1和Component_Sub_2平行
- Component_Super含
this.state.count,按钮每点击一次 count+1 - Component_Sub_1和Component_Sub_2含
this.state.count,按钮每点击一次 count+1; - Component_Sub_1含
this.props.count,值为Component_Super中this.state.count;
实例化周期
页面加载后,观察控制台输出:

- 执行
getDefaultProps方法- 三组件中,此方法首先被执行
getDefaultProps属于组件类方法,而非组件实例方法,在组件类定义后执行;即:只要此class被定义,无论是否使用,无论使用多少次,其中定义的getDefaultProps方法都会被执行,且仅执行一次
- 父组件Super执行
componentDidMount- 父组件的
componentDidMount方法会在其render的全部内容装载到DOM后执行,若父组件中包含定义的子组件,则componentDidMount方法会在子组件执行完实例化周期后再执行
- 父组件的
- 子组件Sub1、Sub2执行
componentDidMount- 多个子组件平行,并非依次执行实例化周期(getInitialState->componentWillMount->render->componentDidMount),而是待所有所有平行子组件首次render后,再依次执行
componentDidMount
- 多个子组件平行,并非依次执行实例化周期(getInitialState->componentWillMount->render->componentDidMount),而是待所有所有平行子组件首次render后,再依次执行
更新期
点击Sub1/Sub2中[count+1]按钮


- Sub1执行更新期方法
- 所有执行的方法均为Sub1组件周期方法,而不行执行其平行组件Sub2及父组件Super中的方法
点击Super中[count+1]按钮


- Super执行更新期方法
- state变化触发Super依次执行更新期方法(shouldComponentUpdate->componentWillUpdate->render->componentDidUpdate),其中
componentDidUpdate会在全部子组件更新完毕后执行
- state变化触发Super依次执行更新期方法(shouldComponentUpdate->componentWillUpdate->render->componentDidUpdate),其中
- Sub1、Sub2执行更新期方法
- Sub1接收父组件值
this.props.count,而Sub2未接收任何父组件传值,但两子组件的componentWillReceiveProps都被执行,故只要当前组件作为子组件渲染,注册了componentWillReceiveProps,此方法都会在父组件变更后执行 - 尽管Sub2未接收任何父组件传值,但当Super更新时,Sub2仍执行了整个更新期的方法,故父组件的变更会导致其下所有子组件进入更新期
- Sub1接收父组件值
卸载期
点击卸载Sub1


- Super执行更新期方法
- state变化触发Super依次执行更新期方法(shouldComponentUpdate->componentWillUpdate->render->componentDidUpdate)
- Sub1执行卸载期方法
- Sub1进入卸载期后,仅执行
componentWillUnmount,并在所有同级组件render后执行
- Sub1进入卸载期后,仅执行
点击卸载Super

- Sub1、Sub2依次执行
componentWillUnmount - Super执行
componentWillUnmount- 由于卸载Super直接调用方法
ReactDOM.unmountComponentAtNode(),故并未执行Super的componentWillUnmount方法;但若是通过状态变更将Super卸载,其componentWillUnmount方法将会在Sub1、Sub2执行componentWillUnmount前执行
- 由于卸载Super直接调用方法
[React] 多组件生命周期转换关系的更多相关文章
- React 之 组件生命周期
React 之 组件生命周期 理解1) 组件对象从创建到死亡它会经历特定的生命周期阶段2) React组件对象包含一系列的勾子函数(生命周期回调函数), 在生命周期特定时刻回调3) 我们在定义组件时, ...
- [深入React] 7.组件生命周期
生命周期一共分三段:初始化,运行中,销毁.按照顺序: 初始化 getDefaultProps():Object 全局只会调用一次,为当前类生成的默认props,会被父组件传入的同名props覆盖. g ...
- React Class组件生命周期
一.react组件的两种定义方式 1.函数组件,简单的函数组件像下面这样,接收Props,渲染DOM,而不关注其他逻辑 function Welcome(props) { return <h1& ...
- react之组件生命周期
四个阶段 初始化 运行中 销毁 错误处理(16.3以后) 初始化 constructor static getDerivedStateFromProps() componentWillMount() ...
- 【JAVASCRIPT】React学习-组件生命周期
摘要 整理组件加载过程,详细见官方文档:https://facebook.github.io/react/docs/react-component.html mount 过程 1)constructo ...
- 【React】组件生命周期
初始化阶段 getDefaultPropos:只调用一次,实力之间共享引用 getInitialState:初始化每个实例特有的状态 componentWillMount:render之前最后一次修改 ...
- React.js 小书 Lesson20 - 更新阶段的组件生命周期
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson20 转载请注明出处,保留原文链接和作者信息. 从之前的章节我们了解到,组件的挂载指的是将组件 ...
- React组件生命周期小结
React组件生命周期小结 下面所写的,只适合前端的React.(React也支持后端渲染,而且和前端有点小区别,不过我没用过.) 相关函数 简单地说,React Component通过其定义的几个函 ...
- react学习(6)——关于组件生命周期的问题
在项目开发的过程中,遇到了一个问题: 父组件请求后台数据,收到后将数据以props传给子组件,子组件根据收到数据的不同,显示不同的内容,同时,子组件自身可以根据click操作改变根据父组件的数据显示的 ...
随机推荐
- 错误提示,解决方案java.lang.UnsatisfiedLinkError: Couldn't load easemobservice from loader dalvik.system.PathClassLoad
解决方案: 在libs下面创建一个armeabi-v7a文件夹 把armeabi *.so的文件复制一份 放在armeabi-v7a运行测试通过 关于 armeabi和armeabi-v7a 区别如下 ...
- EventBus3.0源码解析
本文主要介绍EventBus3.0的源码 EventBus是一个Android事件发布/订阅框架,通过解耦发布者和订阅者简化 Android 事件传递. EventBus使用简单,并将事件发布和订阅充 ...
- Android Studio导入Vitamio多媒体开发框架
PS:这篇笔记用于解决Android Studio导入Vitamio框架的问题.官网给出的相关说明过于简单,故整理这篇文章,希望能帮助到像我一样遇到这个问题的朋友. 开发学习建议参考农民伯伯的博客中的 ...
- git 远程仓库-github
第1步:创建SSH Key.在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步.如果没有,打开Shell ...
- SqlServer--用代码创建和删除数据库或表
创建数据库,创建表,设置主键数据库的分离和附加MS SQLServer的每个数据库包含:1个主数据文件(.mdf)必须.1个事务日志文件(.ldf)必须.可以包含:任意多个次要数据文件(.ndf)多个 ...
- (转)基于CAS实现单点登录(SSO):cas client端的退出问题
出处:http://blog.csdn.net/tch918/article/details/22276627 自从CAS 3.4就很好的支持了单点注销功能,配置也很简单. 之前版本因为在CAS服务器 ...
- 深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接(转)
1.内联接(典型的联接运算,使用像 = 或 <> 之类的比较运算符).包括相等联接和自然联接. 内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行.例如,检索 stude ...
- MongoDB学习笔记~管道中的分组实现group+distinct
回到目录 mongoDB的管道是个好东西,它可以将很多操作批处理实现,即将多个命令放入一个管道,然后去顺序的执行它们,今天我要说的是,利用管道中的分组来实现实现中的ditinct+group的效果,即 ...
- 关于 Java 数组的 12 个最佳方法
1. 声明一个数组 String[] aArray = new String[5]; String[] bArray = {"a","b","c&q ...
- 迅为-iMX6开发板 飞思卡尔iMX6Q开发板 工业级开发板
了解详情请点击迅为官网:http://topeetboard.com 迅为-i.MX6开发板是采用Freescale Cortex-A9 四核i.MX6Q处理器,主频1GHz,2G DDR3内存,16 ...