🔥 除了 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 在卸载组件时会调用带有 nullref 函数。现在,如果 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} />
  );
}

如果提供了 initialValueuseDeferredValue 会将其作为组件初始渲染的 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 类型是 stringnumber 等原始值或者值为 true,那么它们会渲染为属性。诸如 objectfunction 等非原始值或 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...

相关推荐
m0_7482552618 分钟前
前端安全——敏感信息泄露
前端·安全
鑫~阳2 小时前
html + css 淘宝网实战
前端·css·html
Catherinemin2 小时前
CSS|14 z-index
前端·css
2401_882727573 小时前
低代码配置式组态软件-BY组态
前端·后端·物联网·低代码·前端框架
NoneCoder3 小时前
CSS系列(36)-- Containment详解
前端·css
anyup_前端梦工厂4 小时前
初始 ShellJS:一个 Node.js 命令行工具集合
前端·javascript·node.js
5hand4 小时前
Element-ui的使用教程 基于HBuilder X
前端·javascript·vue.js·elementui
GDAL4 小时前
vue3入门教程:ref能否完全替代reactive?
前端·javascript·vue.js
六卿4 小时前
react防止页面崩溃
前端·react.js·前端框架
z千鑫4 小时前
【前端】详解前端三大主流框架:React、Vue与Angular的比较与选择
前端·vue.js·react.js