React 在今天刚刚在官网发布了有关于 React 18 的计划更新(The Plan for React 18 – React Blog),同时发布了 Alpha 版本的 npm 包:
下载地址:https://reactjs.org/blog/2021/06/08/the-plan-for-react-18.html
最近虽然忙到没时间做视频,不过这么大的事还是值得来聊聊(趁着公司电脑强制要求升 Big Sur 不让不让用的间隙……)。本文并非逐字翻译,一如既往的会带不少个人想法,不代表公司观点(听说这句话其实说了并没什么卵用是吧 Oppo)。
React 18 正式引入了对并发模式/特性的「渐进升级」策略
之前[1]我就提到过 React 18 会把重点放在解决兼容性和如何做迁移的问题上。
自从 Concurrent Mode(并发模式,以下简称 CM)宣布以来,Core Team 成员每天在推上 Github 上「XXX is not CM-safe」吓死个人,使得整个社区都一直在担心未来的 React 是不是会为了上 CM 直接 breaking change,然后不兼容 CM 的代码必须要全部迁移过来才能用 CM("all-or-nothing" upgrade strategy)。
这次 18 的计划发布终于横扫了大家的担忧 —— 并发的引入将会是 opt-in 得,不用的话就没有 breaking changes,整体采用了渐进升级的策略(gradual adoption strategy)。
博文里基本没讲怎么渐进,只是说「升级到 18 几乎不需要任何改动」。其实大概上有两个地方做到了「渐进」:
- React 团队对 "Concurrency opt-in" roots 的兼容性做了很多优化,如果不用 CM 特性的话,大概率能 just works。如博客所说「concurrent rendering will only be enabled for updates triggered by one of the new features.」—— 从此再无 CM,只有 Concurrent Features(并发特性)[2]
- 对于直接想让应用的某一部分「躺平」的可以用 legacy root。我之前在 VLOG 第四期[3]中就和大家提到过,17 对事件系统的修改的目的之一就是为了让你的 React 应用同时可以跑在不同「版本」上[4]。18 的实际做法[5]是引入了新的 Root API
ReactDOM.createRoot
来与旧的ReactDOM.render
API 区分开来,你可以将整个 React 树分形成不同的 roots,用旧 API 的 legacy roots 会跑在「legacy mode 传统模式」上(相当于跑在 17 上),用新 API 的 roots 会跑在 "Concurrency opt-in" roots 下。
React 18 的其他新特性
- 更加激进的「自动 batching」,React 17 只在事件回调中 batch,React 18 则会对任何来源的 setState 做尽可能多的 batching。 如果你跟我一样是用类似 state monad 的 mental model 来思考 state 的话,你可能会以为 React 早就是这个行为了。对于 Hooks 来说你是没有办法拿到中间状态的 state 而 Class 可以拿
this.state
。这也是我以前[6]说过的 class 对比 FC 的纯度问题。 - 新的
startTransition
与useDeferredValue
API,本质上都是允许你将 UI 的一部分标记为「较低的更新优先级」。 - Suspense SSR。你可能知道也不知道的是,完全用 React 重写的新 Facebook.com 是用 Hermes 做 SSR 来优化首屏渲染得,所以 SSR 的优化就成为了 React 团队的优先级之一啦……但是传统 SSR 的一个问题是,全量渲染话延迟太高了。而 CM + Suspence 就可以做到用 Suspence boundary 将应用分片,然后以此为单位做流式 SSR,是不是有重新发明 BigPipe 的感觉了?
- StrictMode 在既 double-render 之后加入了 double-effect
可以看到,随着 CM 的逐渐落地,其「底层能力」的一面终于开始逐渐显著出来,越来越多的上层应用将会发布以及正在开发中(比如 Brian 提到的 Offscreen API 以及 RN Pre-render)等。
React 18 工作组
最后呢就是 React 成立了一个工作组(WG,Working Group)来向整个社区公开有关 18 的讨论与进度。这里的重点是帮助社区的主要框架、类库作者在 18 Alpha 阶段开始迁移,这样当 18 真正发布时社区能够准备充分一些,React 团队一向把开发者体验放在非常高的位置。
React 不用我都不知道 Github 还有 Discussions 这个功能……
Ok 那么今天就先聊到这里~我们下期再见,Peace!
参考
- ^React 的 Concurrent Mode 是否有过度设计的成分? https://www.zhihu.com/question/434791954/answer/1717536954
- ^https://github.com/reactwg/react-18/discussions/4
- ^聊聊 2021 我关注的 JS 趋势、问卷收尾 | 程序员黄玄 Vol 004 https://www.zhihu.com/zvideo/1355161264251994112
- ^https://reactjs.org/blog/2020/08/10/react-v17-rc.html#gradual-upgrades
- ^Replacing render with createRoot https://github.com/reactwg/react-18/discussions/5
- ^React Hooks 是否可以改为用类似 Vue 3 Composition API 的方式实现? https://www.zhihu.com/question/378861485/answer/1125724740