We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
react 16 之前的生命周期图
react 16.4 之后版本的生命周期
为什么我们这里直接跳过 16.0 ~ 16.3 版本,直接说16.4呢?原因是据官方的说法,在新的生命周期 getDerivedStateFromProps react 自身考虑失误,在16.4 纠正了这个错误,所以我们直接来谈 16.4, 下文中的16 之后的版本,也指的是 16.4 之后的版本。
getDerivedStateFromProps
通过两张图的对比我们可以看到,react 16 前后版本的差别:
componentWillMount componentWillReceiveProps ——> getDerivedStateFromProps(nextProps, prevState) componentWillUpdate
getDerivedStateFromProps是一个静态方法,所以不能在这个函数里面使用this,这个函数有两个参数props和state,分别指接收到的新参数和当前的state对象,这个函数会返回一个对象用来更新当前的state对象,如果不需要更新可以返回null。
react 16 + 生命周期的变化
新增了getDerivedStateFromProps 、getSnapshotBeforeUpdate 、componentDidCatch(捕获报错用的,Suspense的实现原理) 三个生命周期,删除了componentWillMount、componentWillReceiveProps、componentWillUpdate三个生命周期。
在 react 16 中 react 公布了新的API -- Time Slice 和 Suspense.
React 在16版本之前 DOM 更新的做法是 边 比较DOM结构 边 更新的,如果发现有变化, 则立即做出响应。
比较DOM结构
更新
下面让我们可以想象这样的例子,
A 节点下面有无数的儿子节点在变化, 恰巧此时我们又在 input 输入的时候,这时,就会造成react 卡在这里,不停的算不停的算,从而整个进程被卡住。
但是现在,我们做到了 Slicing(异步渲染机制), 将「比较」和「更新」分开进行。 比较过程中,(在指定时间段内 猜是16毫秒)当比较完当前节点后,它看看是否还有时间比较下一个节点,如果有的话才会继续比较,如果没有的话,把主线程释放出来,给更紧急的任务;如果真的有更紧急的任务,前面的比较内容会被丢弃。然后等待变化全部结束后,一次性的更新所有内容。
总结一下,react16 的渲染更新分为两个阶段。 第一阶段(reconciliation阶段)比较变化: 这一阶段做的是Fiber的update,然后产出的是effect list(可以想象成将老的View更新到新的状态所需要做的DOM操作的列表)。这一个阶段是没有副作用的,因此这个过程可以被打断,然后恢复执行。
第二阶段(commit阶段 ) 更新不变化,不会别打断。Reconciliation产生的effect list只有在commit之后才会生效,也就是真正应用到DOM中。这一阶段往往不会执行太长时间,因此是同步的,这样也避免了组件内视图层结构和DOM不一致。这样就会带来一个问题:在 react16 之前的版本,经常会有人喜欢在 componentWillMount 时调用 ajax 函数来获取数据,这样造成数据别重复获取。  为了解决这个问题, 就出现了上面的生命周期的变化 --- 废弃 componentWillMount、componentWillReceiveProps、componentWillUpdate 以 getDerivedStateFromProps 取而代之。
componentWillMount
上面提到了 getDerivedStateFromProps 是一个静态函数, 之所以把它设置成一个 静态函数 的目的是:react 不希望你在 第一阶段做任何无用的操作,只需专心的做好state 计算方面的事情。
静态函数
以上本文的主要内容就讲完了,但是前文提到了 Dan 老哥在提出 Time Slice 的同时,还提出了Suspense。下面我们简单介绍一下它。
Suspense 的用法与我们之前书写组件的方式有很大的差异,因为我们知道,在react的render()函数中,异步去fetch数据是没用的,因为异步函数会在下一个JS事件循环中才会进行,此时,已经渲染完毕了。所以拿到数据了也没用。
或者也可以简单的总结为下面的过程: 调用render函数->发现有异步请求->悬停,等待异步请求结果->再渲染展示数据
或者也可以简单的总结为下面的过程:
调用render函数->发现有异步请求->悬停,等待异步请求结果->再渲染展示数据
由此可以看到,我们可以用一种同步的方式去书写代码,就像我们写async/await一样!
看一个Suspense 的例子:
const OtherComponent = React.lazy(() => import('./OtherComponent')); function MyComponent() { return ( <div> <Suspense fallback={<div>Loading...</div>}> <OtherComponent /> </Suspense> </div> ); }
在我们的业务场景中,OtherComponent可以代表多个条件渲染组件,我们全部加载完成才取消loding。
只要promise没执行到resolve,suspense都会返回fallback中的loading。
代码简洁,loading可提升至祖先组件,易聚合。相当优雅的解决了条件渲染。
Suspense的实现与探讨
react 生命周期图片原稿
The text was updated successfully, but these errors were encountered:
No branches or pull requests
react 16 之前的生命周期图
react 16.4 之后版本的生命周期
通过两张图的对比我们可以看到,react 16 前后版本的差别:
componentWillMount
componentWillReceiveProps ——> getDerivedStateFromProps(nextProps, prevState)
componentWillUpdate
为什么要这样改变?
在 react 16 中 react 公布了新的API -- Time Slice 和 Suspense.
Time Slice 时间分片
React16 版本前是如何更新的
React 在16版本之前 DOM 更新的做法是 边
比较DOM结构
边更新
的,如果发现有变化, 则立即做出响应。下面让我们可以想象这样的例子,
A 节点下面有无数的儿子节点在变化, 恰巧此时我们又在 input 输入的时候,这时,就会造成react 卡在这里,不停的算不停的算,从而整个进程被卡住。
但是现在,我们做到了 Slicing(异步渲染机制), 将「比较」和「更新」分开进行。
比较过程中,(在指定时间段内 猜是16毫秒)当比较完当前节点后,它看看是否还有时间比较下一个节点,如果有的话才会继续比较,如果没有的话,把主线程释放出来,给更紧急的任务;如果真的有更紧急的任务,前面的比较内容会被丢弃。然后等待变化全部结束后,一次性的更新所有内容。
react16 版本之后的渲染过程
总结一下,react16 的渲染更新分为两个阶段。
第一阶段(reconciliation阶段)比较变化: 这一阶段做的是Fiber的update,然后产出的是effect list(可以想象成将老的View更新到新的状态所需要做的DOM操作的列表)。这一个阶段是没有副作用的,因此这个过程可以被打断,然后恢复执行。
第二阶段(commit阶段 ) 更新不变化,不会别打断。Reconciliation产生的effect list只有在commit之后才会生效,也就是真正应用到DOM中。这一阶段往往不会执行太长时间,因此是同步的,这样也避免了组件内视图层结构和DOM不一致。这样就会带来一个问题:在 react16 之前的版本,经常会有人喜欢在
componentWillMount
时调用 ajax 函数来获取数据,这样造成数据别重复获取。
为了解决这个问题, 就出现了上面的生命周期的变化 --- 废弃 componentWillMount、componentWillReceiveProps、componentWillUpdate 以 getDerivedStateFromProps 取而代之。
上面提到了 getDerivedStateFromProps 是一个静态函数, 之所以把它设置成一个
静态函数
的目的是:react 不希望你在 第一阶段做任何无用的操作,只需专心的做好state 计算方面的事情。Suspense 悬停(也可以叫做暂停)
以上本文的主要内容就讲完了,但是前文提到了 Dan 老哥在提出 Time Slice 的同时,还提出了Suspense。下面我们简单介绍一下它。
Suspense 的用法与我们之前书写组件的方式有很大的差异,因为我们知道,在react的render()函数中,异步去fetch数据是没用的,因为异步函数会在下一个JS事件循环中才会进行,此时,已经渲染完毕了。所以拿到数据了也没用。
Suspense 的实现过程
由此可以看到,我们可以用一种同步的方式去书写代码,就像我们写async/await一样!
看一个Suspense 的例子:
在我们的业务场景中,OtherComponent可以代表多个条件渲染组件,我们全部加载完成才取消loding。
只要promise没执行到resolve,suspense都会返回fallback中的loading。
代码简洁,loading可提升至祖先组件,易聚合。相当优雅的解决了条件渲染。
Suspense的实现与探讨
react 生命周期图片原稿
The text was updated successfully, but these errors were encountered: