Reactv16.0+ 生命周期

生命周期是一个抽象的概念,在生命周期的整个过程,分成了很多个阶段;

装载阶段(Mount),组件第一次在DOM树中被渲染的过程;
更新过程(Update),组件状态发生变化,重新更新渲染的过程;
卸载过程(Unmount),组件从DOM树中被移除的过程;

React内部为了告诉我们当前处于哪些阶段,会对我们组件内部实现的某些函数进行回调,这些函数就是生命周期函数:

实现componentDidMount函数:组件已经挂载到DOM上时,就会回调;
实现componentDidUpdate函数:组件已经发生了更新时,就会回调;
实现componentWillUnmount函数:组件即将被移除时,就会回调;

我们可以在这些回调函数中编写自己的逻辑代码,来完成自己的需求功能;

我们谈React生命周期时,主要谈的类的生命周期,因为函数式组件是没有生命周期函数的;

这里只谈16.0之后的生命周期,旧生命周期不介绍
React16.0前生命周期.png
React16.0后生命周期.png

生命周期的几个阶段

在React生命周期执行的过程中,因为Fiber(非阻塞式渲染)的加入,又可以在每个阶段中分为三个片:

  • Render 纯净不包含副作用,可能会被React暂停,终止,或重新启动
  • pre-commit 可以读取DOM
  • Commit 可以使用DOM,运行Effect,安排更新
Render 下的生命周期
constructor() 
getDerivedStateFromProps()
shouldComponentUpdate()
render()
getDerivedStateFromError()
pre-commit 下的生命周期
getSnapshotBeforeUpdate()
Commit 阶段下的生命周期
componentDidMount()
componentDidUpdate()
componentDidCatch()
挂载过程

当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:

constructor()
static getDerivedStateFromProps()
render()
componentDidMount()
更新过程

当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序如下:

static getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
卸载过程

当组件从 DOM 中移除时会调用如下方法:

componentWillUnmount()
错误处理

当渲染过程,生命周期,或子组件的构造函数中抛出错误时,会调用如下方法:

static getDerivedStateFromError()
componentDidCatch()

代码地址

常用周期函数:

constructor()

构造函数用于初始化props,state以及绑定this指向,如果不需要这些操作可以省略构造函数,需要注意的是:

  • 构造函数中不能调用setState, 而应该直接给state赋值
  • props是由外部传进来的,所以不能修改props
  • 不推荐将props赋值给state

render()

render函数并不会向dom中插入元素,实际上render只是返回jsx结构,或者是数组,字符串等数据,最终由ReactDOM.render渲染到dom中。
注意:在自定义的类组件中,render函数必须实现,并且render应该为一个根据state和props来返回结果,不造成副作用的纯函数。

componentDidMount()

会在组件插入到DOM结点树时进行调用,且只会执行一次(组件被卸载后会重新调用)
作用:
1、数据请求
2、订阅一些行为(componentWillUnmount取消订阅)

componentDidUpdate(prevProps, prevState, snapshot)

更新完成后会立即调用此方法,但首次渲染不会调用
snapshot的值即为getSnapshotBeforeUpdate的返回值
作用:
1、数据更新后的一些DOM操作
2、props变化后,进行新旧props对比后的一些操作

componentWillUnmount()

会在组件卸载及销毁之前进行调用
不能在此调用setState
作用:
1、取消订阅(removeListener)
2、清除未执行完的异步任务(setTimerout\setInterval)

不常用的生命周期

static getDerivedStateFromProps(nextProps,prevState):state

props变化时被调用,以及每一次render之前都会被调用,若是父组件重新渲染,也会被调用。
用于在props发生改变时改变state相当于被废除的UNSAFE_componentWillReceiveProps()。
静态方法无实例化对象,也就是this是undefeated,无法调用正常React组件方法进行操作!
对于返回值,这个时候会进行一个判断 返回的新state是否发生改变
如果发生改变会停止后续生命周期流程,重新启动一个Update流程,又会调用getDerivedStateFromProps()
如果没有发生改变或是null则会继续后续流程,不会重启一个Update流程
返回值
return newState | null(表示不更新)

shouldComponentUpdate(nextProps, nextState):boolean

在props变化或执行setState时就会被调用,通常情况返回true。若返回false。
这个方法在挂载阶段或者执行forceUpdate时不会执行
一般用于性能优化
返回值
return true(需要组件更新) | false(组件忽略本次更新)

getSnapshotBeforeUpdate(prevProps, prevState):any|null

在最近的更改被提交到DOM元素前,使得组件可以在更改之前获得当前值。
在render之后,dom更新之前回执行这个函数,一般会在此时读取dom更新之前的一些信息(比如滚动条位置)。
此生命周期返回的任意值都会传给componentDidUpdate()做为第三个参数。
通常用来做屏幕滚动的计算,但是具体的变更要放在componentDidUpdate上做。
返回值
return any | null

static getDerivedStateFromError(error);state

当子组件抛出错误会触发这个函数,错误信息为函数的参数,结果可以返回一个新的值来更新state。
组件可以根据更新的state实现一个降级UI,此方法在“render阶段”执行,应该为一个纯函数。
返回值
return newState(需要更新的部分) | null

componentDidCatch(error, info)

错误边界会抓取组件内JS的错误,并记录显示回退UI。它会捕获渲染期间,生命周期方法以及下面整个树的构造函数的错误。
同样当子组件抛出错误的时候回触发,第二个参数为info,其中包含了组件调用栈的信息
这个函数是在“commit阶段”执行的,所以可以在函数中调用setState来更新state。

如果一个 class 组件中

定义了 static getDerivedStateFromError() 或 componentDidCatch() 这两个生命周期方法中的任意一个(或两个)时那么它就变成一个错误边界。
当抛出错误后,请使用 static getDerivedStateFromError() 渲染备用 UI ,使用 componentDidCatch() 打印错误信息。

错误边界不会生效的范围:
  • 事件处理 绑定的click事件之类的
  • 异步代码(例如 setTimeout 或 requestAnimationFrame 回调函数)
    服务端渲染
  • 它自身抛出来的错误(并非它的子组件),注意错误边界仅可以捕获其子组件的错误,它无法捕获其自身的错误。如果一个错误边界无法渲染错误信息,则错误会冒泡至最近的上层错误边界。

移除的生命周期

UNSAFE_componentWillMount()
UNSAFE_componentWillUpdate()
UNSAFE_componentWillReceiveProps()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容