污说React之生命周期

一、写在前面

接触react已有几个月的时间,根据自己的经验总结一下对react生命周期的理解。本文将结合人的一生来“污污的”说一说react组件从出生到死亡传奇的一生。为方便理解,提前约定几个名词:

  • props:表示人的基因,不能改变
  • state:表示人的思想,可以改变
  • setState:表示学习,通过学习,可以改变思想,进而改变这个人

人有生老病死,月有阴晴圆缺。作为一个优秀的前端框架,react组件也同样有自己的生命周期。正确掌握react的生命周期,对写高性能组件会有很大的帮助。react的生命周期和人一样,大致可以分为出生前(实例化)、活着(存在期)、死亡前(销毁期)三个阶段。为便于解释整个周期,文中除了生命周期钩子函数外,还会加入对defaultProps、constructor和render函数的讲解。

二、出生前/实例化

defaultProps

此时的你八字还没一撇,即使这样,但因为你的父母已定,所以你的有些特征还是知道的,比如你几条胳膊几条腿等等,所以如果想设置组件默认的props可以在此处设置

constructor()

此时的你已经开始有了初步形态——卵细胞,虽然还没有形成人形,但是来自父母默认的基因却已经注定你将是男还是女,你的大致长相和性格都在此时有了初步的方向。constructor参数接受两个参数props,context。可以获取到父组件传下来的的props,context

作用:直接在constructor中定义this.state。此时可以访问this.props

componentWillMount()

你在妈妈的肚子里不断发育,有了脑袋有了嘴,有了胳膊也有了腿,但是还没有出生,大家伙都在猜测你长什么样。此时你也很无奈啊,因为你什么也做不了。只能按照父母的基因绘制自己出生后的模样。所以服务端渲染可以在这一阶段完成,该钩子也只能调用一次,因为一生中只能在妈妈肚子里呆一次。

时机:组件初始化时调用,以后组件更新不调用 可调用次数:一次 是否可以设置state:可以。 是否可以操作DOM:不可以。

第一次render()

分娩—这是你一生中最重要的时刻,因为你即将来到世上,以后将会有与众不同的人生。同样此时也是react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行。

是否可以设置state:此时的你除了哭什么都不会,更何况学习呢?

componentDidMount()

出生后就要有自己的身份,这时你的爸爸就要跑到公安局:“唉,警察同志,给我孩子一个身份吧!”,警察同志说好,123456这个号码就是你孩子的。这样你以后就可以做很多事情来。拥有身份的过程就是ajax的过程,所以说组件请求ajax数据要在这里进行,因为此时你已经是个看得见摸得着的个体。

时机:组件初次渲染之后立即调用 可调用此次:一次 是否可以设置state:当然,因为你已经出生了 是否可以操作DOM:可以

三、活着/存在期

componentWillReceiveProps(nextProps)

你的基因来自爸爸妈妈,而爸爸的基因则来自爷爷奶奶,所以你们爷俩总会拥有会不同的基因。所以爸爸受基因影响的性格(nextProps)就会想去改变你受基因影响的性格(this.props),你怎么办呢,你就可以通过对比nextProps和this.props,选择自己需要的去学习(setState),然后重新塑造自我。

时机:组件初始化时不调用,组件接受新的props时调用。根据特定的props,更改来触发状态(state)转换。 可调用次数:多次 是否可以设置state:可以。

shouldComponentUpdate(nextProps, nextState)

成长的过程难免会受到各种各样的环境影响,出生决定了你的样貌家庭环境,但你能活成什么样成长对你至关重要。你接受到一个新的思想(state)时是否需要改变呢,比如上幼儿园之前你就知道“我是中国人(this.state)”,到了幼儿园,老师又教你“我是中国人(nextState)”,你都已经知道了,当然没必要去改变了,同样对react也是,可以判断前后两个props和state是否相同,如果相同则返回false阻止更新,可以节省性能。 ps:React15.3开始,对于结构简单的组件,可以使用React.PureComponent替代该函数,react会自动帮助做一层浅比较,减少不必要的 render操作的次数。

时机:react性能优化非常重要的一环,唯一用于控制组件重新渲染的生命周期,setState以后,state发生变化,组件会进入重新渲染的流程,在这里return false可以阻止组件的更新 可调用次数:多次 是否可以设置setState:不可以

componentWillUpdate(nextProps, nextState)

假如上面shouldComponentUpdate返回true,表示你同意要重新学习“我是中国人”,那么你的脑细胞就要重新记忆这个思想。

时机:组件初始化时不调用,只有在组件将要更新时才调用 可调用次数:多次 是否可以设置state:不可以

render()

每次学到了新的东西你都要重新认识自我,更正自己的人生观价值观,同样react在获取新state后都要在这里重新渲染自己一次。

render触发方式

  • 首次渲染Initial Render
  • 调用this.setState (并不是一次setState会触发一次render,React可能会合并操作,再一次性进行render)
  • 父组件发生更新(一般就是props发生改变,但是就算props没有改变或者父子组件之间没有数据交换也会触发render)
  • 调用this.forceUpdate

componentDidUpdate(prevProps, prevState)

此时的你已经学习完成,也再次知道了你是中国人,但你依然会记得之前你是中国人。同理,对于react也是,可以在这里拿到prevProps和prevState,即更新前的props和state。

时机:组件初始化时不调用,组件更新完成后调用,更新DOM以响应prop或state更改。 可调用次数:多次 是否可以设置setState:可以 是否可以获取dom节点:可以

四、死之前/销毁期

componentWillUnmount()

当你老了,没用了,也该离开尘世间了。有的人不需料理后事,两腿一登,就挂了。但有的人麻烦啊,事多,比如古代的皇帝就要交代一下:“死之后要把我那些妃子们一起给我陪葬,不能让她们继续活着”。同理,对于组件,就要在这里清除一些事件监听和定时器,或者取消网络请求,或者清理任何在componentDidMount()中创建的DOM元素(elements)。

时机:组件将要卸载时调用 可调用次数:当然只有一次,人死不能复生啊,亲,要珍爱生命。

五、生命周期执行顺序

1 组件初始化

defaultProps -> constructor -> componentWillMount -> render -> componentDidMount

2 组件更新(props change)

componentWillReceiveProps -> shouldComponentUpdate -> componentWillUpdate -> render -> componentDidUpdate

3 组件更新(state change)

shoudlComponentUpdate -> componentWillUpdate -> render -> componentDidUpdate

4 组件卸载或销毁

componentWillUnmount

5 父子组件间执行顺序

5.1 constructor、componentWillMount、render执行顺序:

顶层父组件--子组件--子组件--...--底层子组件

5.2 componentDidMount顺序

底层子组件--子组件--子组件--...--顶层父组件

六、React 16.3的变化

从16.3版本开始,react生命周期去掉了componentWillMount、componentWillReceiveProps、componentWillUpdate三个,新增了 static getDerivedStateFromProps和getSnapshotBeforeUpdate两个。

static getDerivedStateFromProps(nextProps, prevState)

注意必须有static。 每次接收新的props之后都会返回一个对象作为新的state,返回null则说明不需要更新state。 配合componentDidUpdate,可以覆盖componentWillReceiveProps的所有用法

时机:在组件构建之后(虚拟dom之后,实际dom挂载之前) ,以及每次获取新的props之后。

getSnapshotBeforeUpdate(prevProps, prevState)

返回一个值,作为componentDidUpdate的第三个参数。 配合componentDidUpdate, 可以覆盖componentWillUpdate的所有用法。

时机:update发生的时候,在render之后,在组件dom渲染之前。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值