react生命周期的迭代

目录

1.  react15版本的有以下组成

 2.  16版本的生命周期:

 3.  15版本和16版本的差异:

(1) mounting阶段

(2) updating阶段,如下图比较

改变背后的第一个“Why”:为什么要用 getDerivedStateFromProps 代替 componentWillReceiveProps?

第二个改变

(3) 组件卸载无改变

总结:为啥要做这些改变?

换个角度看生命周期工作流:

总结:render在执行过程中允许被打断,而commit阶段总是同步执行的,

为什么这么设计呢?

总结:render 阶段是允许暂停、终止和重启的,这就导致 render 阶段的生命周期都是有可能被重复执行的

全文总结:React 16 改造生命周期的主要动机是为了配合 Fiber 架构带来的异步渲染机制针对生命周期中长期被滥用的部分推行了具有强制性的最佳实践,确保了 Fiber 机制下数据和视图的安全性,同时也确保了生命周期方法的行为更加纯粹、可控、可预测 


1.  react15版本的有以下组成

分大图解读:

所有render之前的:在执行过程中不会去操作真实的dom,只是把需要渲染的内容返回出来,render以后的生命周期才能进行一些真实dom的操作 

(1)mounting阶段:组件的初始化渲染(挂载)执行一次

componentDidMount:在渲染结束后被触发,此时真实dom已经挂载到了页面,可以在这里进行执行关于真实DOM的操作,异步请求和数据初始化可以在此执行

(2)updating阶段:组件的更新:如上图updating标注

引用React官方:《如果父组件导致组件重新渲染,即使props没有改,也会调用此方法》(componentWillReceiveProps)如果只想处理更改,请确保进行当前值与变更值的比较 

 !!!!!!componentReceiveProps并不是由props的变化触发的,而是由父组件的更新触发的。如果想要改变这个周期,需要加上当前值和更新值得判断

子组件更新会触发shouldCompontUpdate一系列的方法,更新完以后触发compontDidUpdate的执行以后,通知父组件组件子组件更新完毕。

React组件会根据shouldComponetUpdate的返回值(默认值为true是更新的意思)来决定是否执行该方法之后的生命周期进而决定是否对组件进行re-render(重渲染)如下图

通常在这里面进行有条件的判断

(3)componentWillUnmount()组件卸载:

  出现的情况有:

  •      子组件在父组件中被移除了。
  •      组件中设置了key属性,父组件在render过程中发现key和上次的不一样就会干掉。

 2.  16版本的生命周期:

16.3和16.4有点微调

下面是16.4+

 下面是16.3

他们的主要区别在于更新流程触发geyderivedStateFromProps,16.3只有父组件的更新才会触发,16.4任何因素的更新都会触发。

 3.  15版本和16版本的差异:

(1) mounting阶段

不同之处:废弃了componentwWillMount,新增了getDerivedStateFromProps(),如上图
注:16对render方法也进行了一些改动,16之前,render必须返回单个元素,16允许返回元素数组和字符串
getDerivedStateFromProps()解读
注意:getDerivedStateFormProps不是componentdidmount的替代品(因为之前的鸡肋,也危险,不值得被代替而是应该被废弃),getDerivedStateFromProps,(设计初衷不是为了替换componentwillmount,而是替换componetwiillreceiveprops)因此,有且只有一个用途:使用props来派生/更新state ,(直接从命名层面约束用途)在更新和挂载阶段都会存在。
用法和注意事项
  •    他是一个静态方法,不依赖组件实例存在,因此访问不到this,写了this xx就报错,
  •    接收两个参数,state(当前组件的state)和props(父组件的props)如下图,
  •    需要一个对象格式的返回值。没有指定返回值会被警告,因为react需要用返回值更新组件的state,当你确实不存在用state派生props时,可以省略这个生命周期,否则就return null 
注意:此方法对于state的更新并非”覆盖“式的更新,而是针对某个属性的定向更新。

(2) updating阶段,如下图比较

  1. 改变背后的第一个“Why”:为什么要用 getDerivedStateFromProps 代替 componentWillReceiveProps?

  • getDerivedStateFromProps 是作为一个试图代替 componentWillReceiveProps 的 API 而出现的
  • getDerivedStateFromProps 不能完全和 componentWillReceiveProps 画等号
  • getDerivedStateFromProps 可以代替 component will Receive Props,实现基于 props 派生 state 
原则上来说getDerivedStateFromProps能做且只能做这一件事
getDerivedStateFromProps这个API,正是做了 “合理的减法”,从 getDerived StateFromProps 直接被定义为 static 方法这件事上就可见一斑,React 16 在强制推行
“只用 getDerivedStateFromProps 来完成props 到 state 的映射” (目的)为了确保生命周期函数的行为更可控可以预测,从根源上帮开发者避免不合理的编程方式和避免生命周期的滥用,同时也是为新的fiber架构铺路。

第二个改变

应用场景:如下,对比更新前后的数据,获取真实的dom信息
    
getSnapshotBeforeUpdate想要发挥作用离不开componetdidupdate的配合
为什么componetwillupdate为啥非死不可?原因是挡了fiber的路

(3) 组件卸载无改变

总结:为啥要做这些改变?

根本原因是fiber架构,fiber是react16对于react核心算法的一次重写,会使原本同步的渲染过程变成异步的,同步渲染(对于用户是可见的)和异步渲染(异步是对于用户不可见的)
因为react16之前,每次触发组件的更新的时候,都会构建一个新的虚拟dom树,通过与上一次的虚拟dom树diff,实现对dom的定向更新,这个过程是一个递归的过程,如下图
只有最底层的调用返回了,整个渲染过程才会开始逐层返回,这个漫长且不可打断的更新过程将会带来用户体验层面的巨大风险,同步渲染一旦开始就会抓住主线称不放,直到递归彻底完成,在这个过程中,浏览器无法处理其他事情,若渲染时间长,页面会卡顿,而react16引入的fiber架构恰好可以解决这一风险:fiber会将一个大的更新任务拆解为很多个小任务,每当执行一个小任务的时候,渲染线程都会把主线程交回去,看看有没有优先级更高的工作和处理,确保不会出现其他任务被扼死的情况,进而避免同步渲染带来的卡顿,在这个过程中,渲染线程可以被打断也就是异步渲染,如下图

换个角度看生命周期工作流:

fiber架构的重要特征就是可以被打断的异步渲染模式: 这个打断有原则的,根据能否被打断这一标准,react16的生命周期被划分为render和commit两个阶段,commit被细分pre commit和commit
  • Render阶段(上图蓝色部分):render纯净且没有副作用,可能会被react暂停,终止或者重新启动。
  • pre-commit阶段:可以使用dom ,
  • commit:可以使用dom ,运行副作用和安排更新

总结:render在执行过程中允许被打断,而commit阶段总是同步执行的,

为什么这么设计呢?

由于render阶段对于用户不可见,0感知,commit阶段操作涉及真实dom的渲染,不敢在用户眼皮子底下重复渲染

总结:render 阶段是允许暂停、终止和重启的,这就导致 render 阶段的生命周期都是有可能被重复执行的

所以
• componentWil|Mount
• componentWillUpdate
• componentWillReceiveProps
它们都处于render 阶段,都可能重复被执行,就被废弃了
举个例子:如下情况
(1) 以上情况完全可以转移到其他生命周期 (尤其是 componentDidxxx)里去做, 异步请求再怎么快也快不过 (React 15 下的版本) 同步的生命周期首次渲染依然会在数据返回之前执行。
(2)在Fiber 带来的异步渲染机制下,可能会导致非常严重的 Bug,由于 render 阶段里的生命周期都可以重复执行,在 componentwillxxx 被打断+ 重启多次后,就会所以为啥要用getderivedstatefromprops,避免开发者触碰this,避免各种危险骚操作
(3)即使你没有开启异步,React 15 下也有不少人能把自己 “玩死”,在componetwillreceiveprops和componetwillupdate滥用setstate导致死循环。

全文总结:React 16 改造生命周期的主要动机是为了配合 Fiber 架构带来的异步渲染机制针对生命周期中长期被滥用的部分推行了具有强制性的最佳实践,确保了 Fiber 机制下数据和视图的安全性,同时也确保了生命周期方法的行为更加纯粹、可控、可预测 

注:官方给出的例子防止骚操作:You Probably Don't Need Derived State – React Blog

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值