共计 2325 个字符,预计需要花费 6 分钟才能阅读完成。
大家好,我卡颂。
置信很多关注 React
停顿的敌人都理解 Concurrent Mode
,他是 渐进降级 策略的产物。
因为策略调整,依据 What happened to concurrent mode?,在 v18
中将不会有 Concurrent Mode
了。
没有 Concurrent Mode
,那该如何应用 并发更新
呢?
一句话总结:在 v18 中,不再有三种模式,而是以 是否应用并发个性 作为 是否开启并发更新 的根据。
更具体的解释,让咱们一起从 React
渐进降级策略的演进过程中寻找答案。
欢送退出人类高质量前端框架群,带飞
React 有多少种架构?
从最老的版本到以后的 v18,市面上有多少个版本的React
?
能够从架构角度来概括下,以后一共有两种架构:
- 采纳不可中断的 递归 形式更新的
Stack Reconciler
(老架构) - 采纳可中断的 遍历 形式更新的
Fiber Reconciler
(新架构)
新架构能够抉择是否开启 并发更新
,所以以后市面上所有React
版本肯定属于如下一种状况:
- 老架构(v15 及之前版本)
- 新架构,未开启并发更新,与状况 1 行为统一(v16、v17 默认属于这种状况)
- 新架构,未开启并发更新,然而启用了一些新性能(比方
Automatic Batching
) - 新架构,开启并发更新
现实与事实的差距
React
团队的愿景是:
应用老版本的开发者能够逐渐降级到新版,即从状况 1、2、3 向状况 4 降级。
然而这两头存在极大的阻力,因为状况 4 的 React
一些行为异于状况 1、2、3。
比方如下三个生命周期函数在状况 4 的 React 下是“不平安的”:
componentWillMount
componentWillReceiveProps
componentWillUpdate
贸然降级可能造成老代码不兼容。
为了让宽广开发者可能平滑过渡,React
团队采纳了 渐进降级 计划。
渐进降级第一步
渐进降级 计划的第一步是标准代码。
v16.3 新增了 StrictMode
,对开发者编写的 不合乎并发更新标准的代码 作出提醒,逐渐疏导开发者写出标准代码。
比方,应用上述 不平安的 生命周期函数时会产生如下报错信息:
渐进降级第二步
下一步,React
团队让不同状况的 React
能够在同一个页面共存,借此能够让状况 4 的 React
逐渐渗入原有的我的项目。
具体做法是提供三种开发模式:
Legacy
模式,通过ReactDOM.render(<App />, rootNode)
创立的利用遵循该模式。默认敞开StrictMode
,体现同状况 2Blocking
模式,通过ReactDOM.createBlockingRoot(rootNode).render(<App />)
创立的利用遵循该模式,作为从 Legacy
向Concurrent
过渡的两头模式,默认开启StrictMode
,体现同状况 3Concurrent
模式,通过ReactDOM.createRoot(rootNode).render(<App />)
创立的利用遵循该模式,默认开启StrictMode
,体现同状况 4
为了让不同模式的利用能够在同一个页面内工作,须要调整一些底层实现。
比方:调整之前,大多数事件会对立冒泡到 HTML 元素
,调整后事件会冒泡到利用所在 根元素
。
这些调整工作产生在 v17,所以 v17 也被称作为 开启并发更新 做铺垫的 垫脚石 版本。
最新的渐进降级策略
工夫后退到 2021 年 6 月 8 日,v18 工作组成立。
在与社区进行大量沟通后,React
团队意识到以后的 渐进降级 策略存在两方面问题。
起因一
首先,因为模式影响的是整个利用,所以无奈在同一个利用中实现渐进降级。
举个例子,开发者将利用中 ReactDOM.render
改为 ReactDOM.createBlockingRoot
,从Legacy
模式切换到 Blocking
模式,这会主动开启StrictMode
。
此时,整个利用的 并发不兼容正告 都会上报,开发者还是须要批改整个利用。
从这个角度看,并没有起到 渐进降级 的目标。
起因二
其次,React
团队发现:开发者从新架构中获益,更多是因为应用了 并发个性
(Concurrent Feature
)。
并发个性
指开启 并发更新
后能力应用的个性,比方:
useDeferredValue
useTransition
所以,能够默认状况下仍应用 同步更新
,在应用了 并发个性
后再开启 并发更新
。
在 v18 中运行如下代码:
const App = () => {const [count, updateCount] = useState(0);
const [isPending, startTransition] = useTransition();
const onClick = () => {
// 应用了并发个性 useTransition
startTransition(() => {
// 本次更新是并发更新
updateCount((count) => count + 1);
});
};
return <h3 onClick={onClick}>{count}</h3>;
};
因为 updateCount
在startTransition
的回调函数中执行(应用了 并发个性
),所以updateCount
会触发 并发更新
。
如果 updateCount
没有作为 startTransition
的回调函数执行,那么 updateCount
将触发默认的 同步更新
。
你能够察看这两种状况是否开启
工夫切片
来辨别是否是并发更新,残缺代码见 Demo 地址
论断
在 v18 中,不再有三种模式,而是以 是否应用并发个性 作为 是否开启并发更新 的根据。
具体来说,在 v18 中对立应用 ReactDOM.createRoot
创立利用。
当不应用 并发个性
时,体现如状况 3。应用 并发个性
后,体现如状况 4。
React18
稳定版最快明年一月底到来,你还学的动吗?