🔥 除了 RSC 等新功能,React 19 还优化了什么?

作者:React 团队

译者:林语冰

资源:React 官方博客1

免责声明:活人翻译,略有删改,仅供粉丝参考!

00. Hello World

大家好,我是大家的 林语冰。

React 官方博客的上半部分主要共享了 React 19 新增的功能,比如 RSC 或 use API 等,而本文主要共享 React 19 相对于旧版所做的 DX 优化或其他改进。

01. ref 作为 prop

React 19 可以访问 ref 作为函数组件的 prop:

jsx 复制代码
function MyInput({placeholder, ref}) {
  return <input placeholder={placeholder} ref={ref} />
}

<MyInput ref={ref} />

新版函数组件不再需要 forwardRef。

注意,传递给类的 refs 不会作为 props 传递,因为它们引用了组件实例。

02. 作为 provider

React 19 可以把 <Context> 渲染为 provider,而不是 <Context.Provider>:

jsx 复制代码
const ThemeContext = createContext('');

function App({children}) {
  return (
    <ThemeContext value="dark">
      {children}
    </ThemeContext>
  );  
}

新的 Context provider 可以使用 <Context>。

03. refs 的清理函数

现在支持从 ref 回调返回清理函数:

jsx 复制代码
<input
  ref={(ref) => {
    // 创建 ref 
    // 当元素从 DOM 中移除时,
    // 现在返回清理函数来重置 ref
    return () => {
      // 清理 ref
    };
  }}
/>

当组件卸载时,React 会调用从 ref 回调返回的清理函数。这适用于 DOM 引用、类组件的引用和 useImperativeHandle。

以前,React 在卸载组件时会调用带有 null 的 ref 函数。现在,如果 ref 返回清理函数,React 会跳过此步骤。

由于引入了 ref 清理函数,从 ref 回调返回任何其他内容现在都会被 TS 拒绝。

解决方案是停用隐式返回,比如:

diff 复制代码
- <div ref={current => (instance = current)} />
+ <div ref={current => {instance = current}} />

04. useDeferredValue 的初始值

useDeferredValue 添加了一个 initialValue 选项:

jsx 复制代码
function Search({deferredValue}) {
  // 初始渲染时值为 ''
  // 重渲染会使用 deferredValue 调度。
  const value = useDeferredValue(deferredValue, '');
  
  return (
    <Results query={value} />
  );
}

如果提供了 initialValue,useDeferredValue 会将其作为组件初始渲染的 value 返回,并使用返回的 deferredValue 在后台调度重新渲染。

05. 支持文档元数据

React 19 支持在组件中原生渲染文档元数据标签:

jsx 复制代码
function BlogPost({post}) {
  return (
    <article>
      <title>{post.title}</title>
      <meta name="keywords" content={post.keywords} />
    </article>
  );
}

当 React 渲染该组件时,它会识别 <title>、<link> 和 <meta> 标记,并自动将它们提升到文档的<head> 部分。

06. 支持样式表

React 19 内置对样式表的支持。

如果你告诉 React 样式表的 precedence,它会管理 DOM 中样式表的插入顺序,并确保在显示依赖这些样式规则的内容之前加载外部样式表。

jsx 复制代码
function ComponentOne() {
  return (
    <Suspense fallback="loading...">
      <link rel="stylesheet" href="foo" precedence="default" />
      <link rel="stylesheet" href="bar" precedence="high" />
    </Suspense>
  )
}

在服务端渲染期间,React 会在 <head> 中包含样式表,这确保浏览器在加载之前不会绘制。如果样式表在我们开始流式传输之后被发现,React 会确保样式表插入到客户端的 <head> 中,然后再显示依赖该样式表的 Suspense 边界的内容。

在客户端渲染期间,React 会等待新渲染的样式表加载,然后再提交渲染。如果你从应用中的多个位置渲染此组件,React 只会在文档中包含一次样式表:

jsx 复制代码
function App() {
  return <>
    <ComponentOne />
    ...
    <ComponentOne />
    // 不会导致 DOM 中出现重复样式表链接
  </>
}

07. 支持异步脚本

React 19 更好地支持异步脚本,允许你在组件树中的任何位置、实际依赖脚本的组件内渲染它们,而无需管理重新定位和重复数据删除的脚本实例。

jsx 复制代码
function MyComponent() {
  return (
    <div>
      <script async={true} src="..." />
    </div>
  )
}

function App() {
  <html>
    <body>
      <MyComponent>
      ...
      <MyComponent>
        // 不会导致 DOM 中的重复脚本
    </body>
  </html>
}

在所有渲染环境中,异步脚本都会被去重,这样即使脚本由多个不同的组件渲染,React 也只会加载并执行一次脚本。

08. 支持预加载资源

React 19 新增许多用于加载和预加载浏览器资源的 API,以便尽可能轻松地构建不受低效资源加载阻碍的出色体验。

这些 API 可用于通过将字体等其他资源的发现移出样式表加载来优化初始页面加载。

它们还可以通过预请求预期导航使用的资源列表,然后在单击甚至挂起时迫切预加载这些资源,从而加快客户端更新速度。

09. 支持自定义元素

React 19 增加了对 自定义元素2 的全面支持,因为旧版 React 将无法识别的 props 视为特性(attributes)而不是属性(properties)。

React 19 添加了对在客户端和 SSR 期间使用的属性的支持,策略如下:

  • 服务器端渲染 :如果传递给自定义元素的 props 类型是 string、number 等原始值或者值为 true,那么它们会渲染为属性。诸如 object、function 等非原始值或 false 值的 props 会被省略。
  • 客户端渲染:与自定义元素实例上的属性匹配的 props 会被赋值为属性(properties),否则会被赋值为特性(attributes)。

高潮总结

React 19 是 React 18 发布两年后再次升级的主版本,除了上一篇官方博客中分享的新功能外,还有本文涉及的开发体验和旧版功能的优化,升级新版时记得参考 迁移指南3。

我是大家的 林语冰 👨‍💻,欢迎持续 关注,随时了解海内外前端开发的最新情报。

谢谢的大家点赞、留言和友情转发,我们下期再见~👍

参考文献

1 React 官方博客: react.dev/blog/2024/1...

2 自定义元素: custom-elements-everywhere.com

3 迁移指南: react.dev/blog/2024/0...

相关推荐
传人once7 小时前
悬停旋转放大和位移效果如何写
javascript·css·动画
库拉镜像AI牛牛7 小时前
短剧内容自动化生产:知漫剧工作室落地教程
大数据·服务器·前端·人工智能·语音识别
律宏阔7 小时前
Flutter 列表图片内存优化:CachedNetworkImage 与 ClipRRect 的取舍
前端·flutter
行者全栈架构师7 小时前
【鸿蒙心迹】相册文搜图工程化落地:HarmonyOS 7.0 端侧 AI 检索全链路实战与 5 个踩坑解法
前端
律宏阔7 小时前
Dart 3 Record:解决 Future.wait 异构返回值的类型问题
前端·flutter
Seraphina367 小时前
DVWA(XSS Reflected/Stored High,CSRF Low)
前端·xss·csrf
默_笙8 小时前
🍔 中间件不只是打日志:四个钩子、一次短路,和自带的工具
前端·javascript
程序员老赵9 小时前
Docker 部署 Dolibarr:轻松搭建开源 ERP/CRM 平台
运维·前端·后端
星禾元亨9 小时前
同一件事有三份资料,AI 该信哪一份?冲突判定、优先级链与处置流程
前端·人工智能
Dovis(誓平步青云)9 小时前
家里设备越来越多,如何用一张空间地图控制灯光和温度![
android·java·前端·javascript·人工智能·电脑