美文网首页
2.React 生命周期

2.React 生命周期

作者: 米古月_f198 | 来源:发表于2021-03-01 10:13 被阅读0次

React15


image.png

可以看到,this.state.ownText 这个状态和子组件完全无关。但是当点击“修改父组件自有文本内容”这个按钮的时候,componentReceiveProps 仍然被触发了,
componentReceiveProps 并不是由 props 的变化触发的,而是由”父组件的更新触发”的,这个结论,要谨记。
React16
16.4


image.png

1)getDerivedStateFromProps 是一个静态方法。
静态方法不依赖组件实例而存在,因此你在这个方法内部是访问不到 this 的。
2)该方法可以接收两个参数:props 和 state,它们分别代表当前组件接收到的来自父组件的 props和当前组件自身的 state
3)getDerivedStateFromProps 需要一个对象格式的返回值。
getDerivedStateFromProps 的返回值之所以不可或缺,是因为 React 需要用这个返回值来更新(派生)组件的 state。因此当你确实不存在“使用 props 派生 state ”这个需求的时候,最好是直接省略掉这个生命周期方法的编写,否则一定记得给它 return 一个 null。

image.png

消失的 componentWillUpdate 与新增的 getSnapshotBeforeUpdate

getSnapshotBeforeUpdate(prevProps, prevState) {
  // ...
}

这个方法和 getDerivedStateFromProps 颇有几分神似,它们都强调了“我需要一个返回值”这回事。 区别在于:getSnapshotBeforeUpdate 的返回值会作为第三个参数给到 componentDidUpdate。它的执行时机是在 render 方法之后,真实 DOM 更新之前。在这个阶段里,我们可以同时获取到更新前的真实 DOM 和更新前后的 state&props 信息。

尽管在实际工作中,需要用到这么多信息的场景并不多,但在对于实现一些特殊的需求来说,没它还真的挺难办。
(ii) 这里举一个非常有代表性的例子:实现一个内容会发生变化的滚动列表,要求根据滚动列表的内容是否发生变化,来决定是否要记录滚动条的当前位置。
这个需求的前半截要求我们对比更新前后的数据(感知变化),后半截则需要获取真实的 DOM 信息(获取位置),这时用 getSnapshotBeforeUpdate 来解决就再合适不过了

React 16 之前存在的风险:

如图所示,同步渲染的递归调用栈是非常深的,只有最底层的调用返回了,整个渲染过程才会开始逐层返回。这个漫长且不可打断的更新过程,将会带来用户体验层面的巨大风险:同步渲染一旦开始,便会牢牢抓住主线程不放,直到递归彻底完成。在这个过程中,浏览器没有办法处理任何渲染之外的事情,会进入一种无法处理用户交互的状态。因此若渲染时间稍微长一点,页面就会面临卡顿甚至卡死t的风险。

Fiber能够解决的:

而 React 16 引入的 Fiber 架构,恰好能够解决掉这个风险:Fiber 会将一个大的更新任务拆解为许多个小任务。每当执行完一个小任务时,渲染线程都会把主线程交回去,看看有没有优先级更高的工作要处理,确保不会出现其他任务被“饿死”的情况,进而避免同步渲染带来的卡顿。在这个过程中,渲染线程不再“一去不回头”,而是可以被打断的,这就是所谓的“异步渲染”,

render 阶段:纯净且没有副作用,可能会被 React 暂停、终止或重新启动。

pre-commit 阶段:可以读取 DOM。

commit 阶段:可以使用 DOM,运行副作用,安排更新。

总的来说,render 阶段在执行过程中允许被打断,而 commit 阶段则总是同步执行的。

带着这个结论,我们再来看看 React 16 打算废弃的是哪些生命周期:

componentWillMount;

componentWillUpdate;

componentWillReceiveProps。

这些生命周期的共性,就是它们都处于 render 阶段,都可能重复被执行,而且由于这些 API 常年被滥用,它们在重复执行的过程中都存在着不可小觑的风险,例如:在“componentWill”开头的生命周期里,你习惯于做的事情可能包括但不限于:

setState();

fetch 发起异步请求;

操作真实 DOM。

这些操作的问题(或不必要性)包括但不限于以下 3 点:

(1)完全可以转移到其他生命周期(尤其是 componentDidxxx)里去做。
比如在 componentWillMount 里发起异步请求。很多人会以为这样做就可以让异步请求回来得“早一点”,从而避免首次渲染白屏。

可惜你忘了,异步请求再怎么快也快不过(React 15 下)同步的生命周期。ComponentWillMount 结束后,render 会迅速地被触发,所以说首次渲染依然会在数据返回之前执行。这样做不仅没有达到你预想的目的,还会导致服务端渲染场景下的冗余请求等额外问题,得不偿失。

(2)在 Fiber 带来的异步渲染机制下,可能会导致非常严重的 Bug。

试想,假如你在 componentWillxxx 里发起了一个付款请求。由于 render 阶段里的生命周期都可以重复执行,在 componentWillxxx 被打断 + 重启多次后,就会发出多个付款请求。
(3)即使你没有开启异步,React 15 下也有不少人能把自己“玩死”。
比如在 componentWillReceiveProps 和 componentWillUpdate 里滥用 setState 导致重复渲染死循环的,那可怕的后果懂得都懂

作者:啊丫丫
链接:https://juejin.cn/post/6916081489130029064
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

相关文章

  • 2.React 生命周期

    React15 可以看到,this.state.ownText 这个状态和子组件完全无关。但是当点击“修改父组件自...

  • 每日一题

    2022年2月25日 1.React生命周期? 2.React的hook和class区别? 3.React的set...

  • 前端开发

    项目准备 1.node环境 2.react + typescript + antd + webpack + mob...

  • 带学习low

    1.代码高亮babeljs.io/docs/editors 2.react tutorial 译者资源

  • 2.React简介

    React 是用于构建用户界面的 JavaScript 库 声明式编写 UI,代码可靠,便于调试 组件化开发,组件...

  • 前端面试知识点集合

    框架: 1.Vue(Nuxt) 2.React 3.Angular JS 1.ECMAScript 1、JavaS...

  • react 框架性能优化

    react 框架性能优化 前端性能监控利器 1.Google Performance工具 2.react 性能查看...

  • react

    [toc] REACT react :1.用来构建用户界面的 JAVASCRIPT 库2.react 专注于视图层...

  • react源码解析2.react的设计理念

    react源码解析2.react的设计理念 视频课程(高效学习):进入课程[https://xiaochen102...

  • react源码解析2.react的设计理念

    react源码解析2.react的设计理念 视频课程(高效学习):进入课程[https://xiaochen102...

网友评论

      本文标题:2.React 生命周期

      本文链接:https://www.haomeiwen.com/subject/qabofltx.html