React 19新特性和更新介绍 03 - 改进和增强

React 19新特性和更新介绍 03 - 改进和增强

React 19 于 2024 年 4 月 25 日正式发布,标志着一个重要的里程碑。

此版本带来了各种新功能和改进,以增强开发人员体验和应用程序性能。

React 19 中的改进和增强

1. Ref 作为 Prop

React 19 对 refs 进行了重大改进:
现在您可以将其作为 props 传递给功能组件(functional components)。这在大多数情况下消除了对 forwardRef 高阶组件 (HOC) 的需求。
新的函数组件(function components)将不再需要 forwardRef,我们将发布 codemod 来自动更新您的组件以使用新的 ref prop。
在未来的版本中,我们将弃用并删除 forwardRef。

关键改进

  • 使用 Refs 的更简单的功能组件:以前,功能组件无法直接将 refs 作为 props 接收。使用 React 19,您可以使用标准 prop 语法传递 refs,使功能组件在与 DOM 元素交互时更加灵活。
  • 减少样板:通过消除对 forwardRef 的需求,您的代码变得更干净、更简洁。这简化了组件创建并提高了可读性。
  • 向后兼容性:对于需要将 ref 传递给类组件或深度嵌套的功能组件层次结构的场景,React 19 仍然支持 forwardRef HOC。使用 forwardRef 的现有代码将继续按预期运行。

示例:


<MyInput ref={ref} />


function MyInput({placeholder, ref}) {
  return <input placeholder={placeholder} ref={ref} />
}

2. Hydration Error 的差异

我们通过改进错误报告的方式,使发现 React 中的错误变得更加容易。之前,它只会显示一堆错误,而不会解释出了什么问题。现在,它会显示一条清晰的消息,详细说明不同之处。

3. Context as a Provider

在 React 19 中,你可以将 <Context> 渲染为 Provider ,而不是 <Context.Provider>

示例:

const ThemeContext = createContext('');

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

4. Refs 的清理函数

React 19 为 refs 引入了一项新功能:能够从 ref 回调中返回清理函数。
这允许在组件卸载时更好地管理资源。

主要改进

  • 自动清理:当组件卸载时,React 将自动调用从 ref 回调返回的清理函数。这可确保正确清理与 ref 相关的资源,例如删除事件侦听器、关闭订阅或释放内存。
  • 提高代码可读性:通过在 ref 回调中明确定义清理逻辑,您的代码变得更易读和更易于维护。您可以在创建 ref 的同时跟踪资源管理。
  • 减少内存泄漏:通过确保正确清理,您可以防止 React 应用程序中的内存泄漏。这对于长时间运行的组件或处理外部资源的组件尤其重要。

示例:

<input
  ref={(ref) => {
    // ref created

    // NEW: return a cleanup function to reset
    // the ref when element is removed from DOM.
    return () => {
      // ref cleanup
    };
  }}
/>

5. 支持文档元数据 ( Document Metadata )

React 19 通过一项新功能简化了文档元数据(标题、描述、元标记)的管理:内置对文档元数据的支持。此改进简化了 SEO(搜索引擎优化)并增强了对文档 <head> 部分的控制。

主要改进

  • 专用组件:React 19 引入了 DocumentHead 组件。这允许您在 React 组件中声明性地定义元数据元素。与传统方法相比,这种方法改善了代码组织和可读性。
  • 简化的 SEO 管理:通过在 DocumentHead 中集中元数据管理,您可以轻松地直接在 React 应用程序中控制标题、描述和其他与 SEO 相关的元素。这使 SEO 管理更加高效。
  • 减少样板:使用 DocumentHead 无需手动操作字符串或复杂的解决方法来更新文档元数据。这可以使代码更干净、更简洁。

在 HTML 中,文档元数据标签(如 <title><link><meta>)保留用于放置在文档的 部分中。在 React 中,决定哪些元数据适合应用的组件可能距离渲染 <head> 的位置非常远,或者 React 根本不渲染 <head>。过去,这些元素需要手动插入到效果中,或者通过 react-helmet 等库插入,并且在服务器渲染 React 应用程序时需要小心处理。

在 React 19 中,我们添加了对在组件中原生渲染文档元数据标签的支持:

当 React 渲染此组件时,它将看到 <title><link><meta> 标签,并自动将它们提升到文档的 <head> 部分。通过原生支持这些元数据标签,我们能够确保它们适用于仅限客户端的应用程序、流式 SSR 和服务器组件。


function BlogPost({post}) {
  return (
    <article>
      <h1>{post.title}</h1>
      <title>{post.title}</title>
      <meta name="author" content="Josh" />
      <link rel="author" href="https://twitter.com/joshcstory/" />
      <meta name="keywords" content={post.keywords} />
      <p>
        Eee equals em-see-squared...
      </p>
    </article>
  );
}

6. 样式表支持

React 19 为管理 React 组件中的样式表引入了重大改进:内置样式表支持,包括外部链接样式表和内联样式。此增强功能简化了样式的应用方式,并确保在不同场景中正确呈现。

主要改进

改进的样式表管理:React 19 控制 DOM 中的样式表加载和插入顺序。这消除了在呈现组件之前应用样式的潜在问题。
声明性控制:您可以直接在组件中指定样式表依赖项,从而更轻松地管理特定于特定组件或组件组的样式。
减少样板:React 处理样式表管理的复杂性,减少了对手动解决方法或复杂样式库的需求。

由于样式优先规则,样式表(包括外部链接 (<link rel="stylesheet" href="...">) 和内联 (<style>...</style>))都需要在 DOM 中仔细定位。构建允许在组件内组合的样式表功能非常困难,因此用户通常要么将所有样式加载到可能依赖它们的组件之外,要么使用封装了这种复杂性的样式库。

在 React 19 中,我们解决了这种复杂性,并通过内置对样式表的支持,提供与客户端并发渲染和服务器流式渲染的更深入集成。如果您告诉 React 样式表的优先级,它将管理样式表在 DOM 中的插入顺序,并确保在显示依赖于这些样式规则的内容之前加载样式表(如果是外部的)。

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

示例:


function ComponentOne() {
  return (
    <Suspense fallback="loading...">
    
      <link rel="stylesheet" href="foo" precedence="default" />
      <link rel="stylesheet" href="bar" precedence="high" />
      
      <article class="foo-class bar-class">
        {...}
      </article>
    </Suspense>
  )
}

function ComponentTwo() {
  return (
    <div>
      <p>{...}</p>
      
      <-- 通过 precedence 属性,will be inserted between foo & bar -->
      <link rel="stylesheet" href="baz" precedence="default" /> 
      
    </div>
  )
}

7. 支持异步脚本

React 19 为处理组件中的异步脚本带来了令人欣喜的改进:更好地支持异步脚本。这简化了管理组件树中异步加载且可能以任何顺序加载的脚本。

主要改进

  • 灵活的脚本放置:异步脚本现在可以放置在组件树中的任何位置,而无需担心重复或重新定位。React 确保每个脚本只加载和执行一次,即使多个组件渲染它也是如此。
  • 减少样板:您不再需要实现复杂的逻辑来管理脚本加载顺序或重复数据删除。React 会自动处理这些方面,从而简化您的代码。
  • 提高代码可读性:通过将异步脚本放置在依赖它们的组件附近,您的代码变得更加直观且更易于维护

在 HTML 中,普通脚本 (<script src="...">) 和延迟脚本 (<script defer="" src="...">) 按文档顺序加载,这使得在组件树深处渲染这些类型的脚本变得具有挑战性。然而,异步脚本 (<script async="" src="...">) 将按任意顺序加载。

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

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

在服务器端渲染中,异步脚本将包含在 中,并在绘制的更重要的资源之后再加载(例如样式表、字体和图像预加载)。

有关更多详细信息,请阅读 <script> 的文档。


function MyComponent() {
  return (
    <div>
      <script async={true} src="..." />
      Hello World
    </div>
  )
}

function App() {
  <html>
    <body>
      <MyComponent>
      ...
      <MyComponent> // won't lead to duplicate script in the DOM
    </body>
  </html>
}

8. 支持预加载资源

React 19 引入了一项重大的性能优化改进:内置支持预加载字体、脚本和样式表等资源。这允许您在用户与初始页面内容交互时主动在后台获取这些资源。

关键改进

  • 更快的页面加载:通过预加载资源,浏览器可以在渲染迫切需要它们之前获取它们,从而带来更流畅的用户体验和更快的感知加载时间。
  • 改进的用户体验:预加载资源减少了初始页面加载后需要下载的内容量,从而为用户带来更无缝的体验,尤其是在连接速度较慢的情况下。
  • 声明性控制:您可以通过 React 19 使用新的浏览器 API,如预加载、预取和预连接,从而在组件内提供对资源预加载的声明性控制。

在初始文档加载和客户端更新期间,尽早告知浏览器可能需要加载的资源会对页面性能产生巨大影响。

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


import { prefetchDNS, preconnect, preload, preinit } from 'react-dom'

function MyComponent() {
  // 急切地加载并执行此脚本
  preinit('https://.../path/to/some/script.js', {as: 'script' }) 
  
  // 预加载此字体
  preload('https://.../path/to/font.woff', { as: 'font' }) 
  
  // 预加载此样式表
  preload('https://.../path/to/stylesheet.css', { as: 'style' }) 
  
  // 当您实际上可能没有向此主机请求任何内容时
  prefetchDNS('https://...') 
  
  // 当你提出请求但不确定具体内容时
  preconnect('https://...') 
}

上述代码将生成以下 DOM/HTML:


<html>
  <head>
    <!-- links/scripts 的优先级取决于它们在早期加载时的实用性,而不是调用顺序 -->
    <link rel="prefetch-dns" href="https://...">
    <link rel="preconnect" href="https://...">
    <link rel="preload" as="font" href="https://.../path/to/font.woff">
    <link rel="preload" as="style" href="https://.../path/to/stylesheet.css">
    <script async="" src="https://.../path/to/some/script.js"></script>
  </head>
  <body>
    ...
  </body>
</html>

这些 API 可用于优化初始页面加载,方法是将字体等其他资源的发现移出样式表加载。
它们还可以通过预取预期导航使用的资源列表,然后在点击或悬停时热切地预加载这些资源,从而加快客户端更新速度。

有关更多详细信息,请参阅资源预加载 API。
https://react.dev/reference/react-dom#resource-preloading-apis




上一篇:React 19新特性和更新介绍 02 - 服务器组件

https://www.cnblogs.com/eddyz/p/18724603




posted @   炎黄子孙,龙的传人  阅读(40)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示