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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库