专栏名称: 前端早读课
我们关注前端,产品体验设计,更关注前端同行的成长。 每天清晨五点早读,四万+同行相伴成长。
目录
相关文章推荐
歸藏的AI工具箱  ·  藏师傅的 Sora 模型初体验报告 ·  昨天  
前端早读课  ·  【早阅】浏览器扩展程序攻击 ·  2 天前  
前端早读课  ·  【早阅】Signals分析:从历史到影响 ·  4 天前  
奇舞精选  ·  奇舞周刊第545期:React 19 正式发布 ·  5 天前  
奇舞精选  ·  奇舞周刊第545期:React 19 正式发布 ·  5 天前  
前端早读课  ·  【第3428期】Speculation ... ·  6 天前  
51好读  ›  专栏  ›  前端早读课

【早阅】React 19 正式发布

前端早读课  · 公众号  · 前端  · 2024-12-07 08:00

正文

作者:@The React Team
原文:https://react.dev/blog/2024/12/05/react-19

回顾下 React 19 的时间线。

  • 在 4 月 25 号发布 React 19 候选版。

  • 在 4 月 25 号至 12 月 5 号持续改进了 React 19,添加了预热 Suspense 树,React Dom 静态 API。

  • 在 24 年 12 月 5 号已正式发布!

此版本带来了许多新功能和改进,旨在提升开发体验和应用性能。现在就来看一看。

React 19 新特性

Actions

背景: React 应用程序中常见的用例是在执行数据变更后更新状态。例如,当用户提交表单更改其名称时,你需要发出 API 请求并处理响应。过去,你需要手动处理待处理状态、错误、乐观更新和顺序请求。

解决方案: React 19 新增了对在转换中使用异步函数的支持,以自动处理待处理状态、错误、表单和乐观更新。

  • useTransition 钩子:处理待处理状态。

  • 动作 (Actions): 自动管理资料提交,包括待处理状态、乐观更新、错误处理和表单处理。

  • useOptimistic 钩子:管理乐观更新。

  • React.useActionState 钩子:处理动作的常见情况。

  •  动作:自动管理表单,并在提交后自动重置表单。

  • requestFormReset API: 手动重置 

  • useFormStatus 钩子:读取父 

     的状态。

新钩子:useActionState

功能:简化动作的常见情况。

用法:接受一个函数(“动作”),并返回一个包装好的动作来调用。当包装好的动作被调用时,useActionState 将返回动作的最后结果作为 data,以及动作的待处理状态作为 pending。

 const [error, submitAction, isPending] = useActionState(
async (previousState, newName) => {
const error = await updateName(newName);
if (error) {
// You can return any result of the action.
// Here, we return only the error.
return error;
}

// handle success
return null;
},
null,
);
React DOM:
 动作

功能:与 React 19 的新 

 特性集成,自动提交表单。

用法:将函数作为 

 和  元素的 action 和 formAction 属性传递。

 <form action={actionFunction}>
React DOM:新钩子:useFormStatus

功能:读取父 

 的状态。

用法:像表单是 Context 提供者一样读取父 

 的状态。

 import {useFormStatus} from 'react-dom';

function DesignButton() {
const {pending} = useFormStatus();
return <button type="submit" disabled={pending} />
}
新钩子:useOptimistic

功能:简化乐观更新的实现。

用法:立即渲染乐观状态,同时异步请求正在进行中。当更新完成或出错时,React 会自动切换回当前值。

 function ChangeName({currentName, onUpdateName}) {
const [optimisticName, setOptimisticName] = useOptimistic(currentName);

const submitAction = async formData => {
const newName = formData.get("name");
setOptimisticName(newName);
const updatedName = await updateName(newName);
onUpdateName(updatedName);
};

return (
<form action={submitAction}>
<p>Your name is: {optimisticName}</p>
<p>
<label>Change Name:</label>
<input
type="text"
name="name"
disabled={currentName !== optimisticName}
/>
</p>
</form>
);
}
新 API:use

功能:在渲染中读取资源。

用法:可以读取 Promise,React 会暂停直到 Promise 解析。也可以读取 Context,允许你有条件地读取 Context,例如在提前返回后。

读取 Promise

 import { use } from 'react';

function Comments({ commentsPromise }) {
// `use` 将会暂停渲染,直到 promise 解析完成。
const comments = use(commentsPromise);
return comments.map(comment => <p key={comment.id}>{comment}</p>);
}

读取 Context

 import { use } from 'react';
import ThemeContext from './ThemeContext';

function Heading({ children }) {
if (children == null) {
return null;
}
// 使用 `useContext` 无法做到这点,因为有提前返回。
const theme = use(ThemeContext);
return (
<h1 style={{ color: theme.color }}>
{children}
</h1>
);
}

限制:不支持在渲染中创建的 Promise。

新的 React DOM 静态 API

功能:改进静态网站生成。

  • API:prerender: 在返回静态 HTML 流之前等待所有资料加载。

  • prerenderToNodeStream: 同上,设计用于 Node.js Streams 和 Web Streams 等流式环境。

 import { prerender } from 'react-dom/static';

async function handler(request) {
const {prelude} = await prerender(<App />, {
bootstrapScripts: ['/main.js']
});
return new Response(prelude, {
headers: { 'content-type': 'text/html' },
});
}

React 服务器组件

服务器组件

功能:在构建之前提前渲染组件。

React 19 支持:包括所有从 Canary 频道包含的 React 服务器组件特性。

服务器动作

功能:允许客户端组件调用在服务器上执行的异步函数。

用法:使用 "use server" 指令定义服务器动作。框架会自动创建对服务器函数的引用,并将该引用传递给客户端组件。当在客户端调用该函数时,React 会向服务器发送请求以执行该函数,并返回结果。

React 19 的改进

ref 作为属性

功能:现在可以访问函数组件的 ref 作为属性。

影响:新的函数组件将不再需要 forwardRef,未来版本将弃用并删除 forwardRef。

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

//...
<MyInput ref={ref} />
水合错误的差异

功能:改进了 react-dom 中水合错误的错误报告。

影响:现在会记录一条包含不匹配差异的消息,而不是记录多条没有任何不匹配信息的错误。

 作为提供者

功能:现在可以使用  作为提供者,而不是 

影响:新的 Context 提供者可以使用 ,未来版本将弃用 

 const ThemeContext = createContext('');

function App({children}) {
return (
<ThemeContext value="dark">
{children}
</ThemeContext>
);
}
refs 的清理函数

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

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

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

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

功能:为 useDeferredValue 添加了 initialValue 选项。

用法:当提供 initialValue 时,useDeferredValue 将在组件的初始渲染中将其作为 value 返回,并在后台使用返回的 deferredValue 安排重新渲染。

 function Search({deferredValue}) {
// On initial render the value is ''.
// Then a re-render is scheduled with the deferredValue.
const value = useDeferredValue(deferredValue, '');

return (
<Results query={value} />
);
}
支持文档元数据

功能:原生支持在组件中渲染文档元数据标签,例如  和 

影响: React 会自动将这些标籤提升到文档的  部分。

 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>
);
}
支持样式表

功能:原生支持样式表,包括外部链接和内联样式表。

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

 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>
<link rel="stylesheet" href="baz" precedence="default" /> <-- will be inserted between foo & bar
</div>
)
}
支持异步脚本

功能:改进了对异步脚本的支持。

用法:可以在组件树中的任何位置渲染异步脚本,而无需管理脚本实例的重新定位和去重复。

 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>
}
支持预加载资源

功能:包含了一组新的 API,用于加载和预加载浏览器资源。

  • prefetchDNS: 当你可能实际上没有从该主机请求任何内容时。

  • preconnect: 当你要请求某些内容但不确定是什麽时。

  • preload: 预加载资源,例如字体、样式表等。

  • preinit: 渴望加载并执行脚本。

 import { prefetchDNS, preconnect, preload, preinit } from 'react-dom'
function MyComponent() {
preinit('https://.../path/to/some/script.js', {as: 'script' }) // loads and executes this script eagerly
preload('https://.../path/to/font.woff', { as: 'font' }) // preloads this font
preload('https://.../path/to/stylesheet.css', { as: 'style' }) // preloads this stylesheet
prefetchDNS('https://...') // when you may not actually request anything from this host
preconnect('https://...') // when you will request something but aren't sure what
}
 
<html>
<head>

<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>
与第三方脚本和扩展的兼容性

功能:改进了水合以考虑第三方脚本和浏览器扩展。

影响:在水合过程中,如果在客户端渲染的元素与服务器 HTML 中找到的元素不匹配,React 将强制进行客户端重新渲染以修复内容。

更好的错误报告
  • 功能:改进了错误处理以消除重複并提供处理捕获和未捕获错误的选项。

  • 选项:onCaughtError: 当 React 在错误边界中捕获到错误时调用。

  • onUncaughtError: 当抛出错误且未被错误边界捕获时调用。

  • onRecoverableError: 当抛出错误并自动恢复时调用。

支持自定义元素

功能:添加了对自定义元素的完全支持。

影响: React 现在将未识别的属性作为属性而不是属性来处理。

最后,😀 每天只需花五分钟即可阅读到的技术资讯,加入【早阅】共学群,可联系 vx:zhgb_f2er

5 分钟技术速览:了解技术资讯的一种方式。

🚀可直接通过阅读原文了解详细内容。