关于前端:React-18不再依赖Concurrent-Mode开启并发了

37次阅读

共计 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 版本肯定属于如下一种状况:

  1. 老架构(v15 及之前版本)
  2. 新架构,未开启并发更新,与状况 1 行为统一(v16、v17 默认属于这种状况)
  3. 新架构,未开启并发更新,然而启用了一些新性能(比方Automatic Batching
  4. 新架构,开启并发更新

现实与事实的差距

React团队的愿景是:

应用老版本的开发者能够逐渐降级到新版,即从状况 1、2、3 向状况 4 降级。

然而这两头存在极大的阻力,因为状况 4 的 React 一些行为异于状况 1、2、3。

比方如下三个生命周期函数在状况 4 的 React 下是“不平安的”:

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

贸然降级可能造成老代码不兼容。

为了让宽广开发者可能平滑过渡,React团队采纳了 渐进降级 计划。

渐进降级第一步

渐进降级 计划的第一步是标准代码。

v16.3 新增了 StrictMode,对开发者编写的 不合乎并发更新标准的代码 作出提醒,逐渐疏导开发者写出标准代码。

比方,应用上述 不平安的 生命周期函数时会产生如下报错信息:

渐进降级第二步

下一步,React团队让不同状况的 React 能够在同一个页面共存,借此能够让状况 4 的 React 逐渐渗入原有的我的项目。

具体做法是提供三种开发模式:

  1. Legacy模式,通过 ReactDOM.render(<App />, rootNode) 创立的利用遵循该模式。默认敞开StrictMode,体现同状况 2
  2. Blocking模式,通过 ReactDOM.createBlockingRoot(rootNode).render(<App />) 创立的利用遵循该模式,作为 从 LegacyConcurrent 过渡的两头模式,默认开启StrictMode,体现同状况 3
  3. Concurrent模式,通过 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>;
};

因为 updateCountstartTransition的回调函数中执行(应用了 并发个性 ),所以updateCount 会触发 并发更新

如果 updateCount 没有作为 startTransition 的回调函数执行,那么 updateCount 将触发默认的 同步更新

你能够察看这两种状况是否开启 工夫切片 来辨别是否是并发更新,残缺代码见 Demo 地址

论断

在 v18 中,不再有三种模式,而是以 是否应用并发个性 作为 是否开启并发更新 的根据。

具体来说,在 v18 中对立应用 ReactDOM.createRoot 创立利用。

当不应用 并发个性 时,体现如状况 3。应用 并发个性 后,体现如状况 4。

React18稳定版最快明年一月底到来,你还学的动吗?

正文完
 0