本文章首发个人网站,欢迎大家订阅:https://tie.pub/blog/react-19-cheat-sheet/
最近知名的 React 开发者 Kent C. Dodds 发表 React 19 的功能更新纪要,精简到一页 PDF。现在我以列表的形式翻译一份:
React Server Components(React 服务器组件)
服务器渲染的组件可以在构建时或根据请求执行。
// dashboard.tsx
import * as db from './db.ts'
import { createOrg } from './org-actions.ts'
import { OrgPicker } from './org-picker.tsx'
// look! it' async
export async function Dashboard() {
// look! await!
const orgs = await db.getOrgs()
{ /* 这是仅在服务端运行的代码 */ }
return (
<div>
<h1>Dashboard</h1>
{/* OrgPicker 是一个客户端组件 */}
<OrgPicker orgs={orgs} onCreateOrg={createOrg} />
</div>
)
}
Actions
异步函数可以自动处理表单提交、错误状态和自动优化更新。
<form action={createOrg} />
useActionState
管理表单状态,在 JavaScript 不可操作时提供等待体验。
const [error, submitAction, isPending] = useActionState(async () => { /* ... */ }, null)
useFormStatus
无需通过逐层传递属性即可访问父表单的状态。
const { pending, data, method, action } = useFormStatus()
useOptimistic
在异步请求进行时显示乐观状态,useOptimistic
。
const [optimisticName, setOptimisticname] = useOptimistic(name)
支持异步脚本
在组件树中的任意位置渲染异步脚本,并自动去重。
<script async src="https://tie.pub/script.js" />
改进的第三方脚本兼容性
在页面水合过程中,<head>
和<body>
中的意外标签会被跳过,避免不匹配错误。
'use client'
标记可以被服务器组件引用并使用客户端 React 功能的代码。
// org-picker.tsx
'use client'
export function OrgPicker({ orgs, onCreateOrg }) {
// orgs, onCreateOrg 属性值可以来自服务端组件
// 这个组件可以使用 useState, useActionState, useEffect,
// useRef 等等
return <div />
}
'use server'
标记可以从客户端代码调用的服务器端函数。
// org-actions.ts
'use server'
// 这个函数可以在客户端调用
export async function createOrg(prevResult, formData) {
// 与 db 一起创建 org
// 返回最终结果
}
支持文档元数据
自动把 <title>
, <meta>
和 <link>
标签提升至 <head>
。
<title>My Blog</title>
<meta name="author" content="Kent" />
样式支持 precedence
属性
支持在并发渲染环境中按优先顺序插入样式表。
<link rel="stylesheet" href="foo.css" precedence="default" />
{ /* 下面的设置在文档中有更高优先级 */ }
<link rel="stylesheet" href="bar.css" precedence="high" />
资源预加载 APIs
预加载字体,脚本和样式等资源来优化性能。
preload('https://example.com/font.woff', { as: 'font' })
preconnect('https://example.com')
支持自定义标签元素
React 现在全面支持自定义标签元素,并且一致地处理属性(properties)和特性(attributes)。
<custom-element prop1="value" />
更好的错误报告
自动去重错误,并为根组件引入 onCaughtError
和 onUncaughtError
处理程序。
createRoot(container, {
onCaughtError(error, errorInfo) {
console.error('Caught error', error, errorInfo.componentStack)
},
onUncaughtError(error, errorInfo) {
console.error('Uncaught error', error, errorInfo.componentStack)
},
})
use
在渲染期间读取资源,例如 promise 或上下文,从而实现条件使用。
const comments = use(commentsPromise)
const theme = use(ThemeContext)
ref
回调清理
ref
回调现在可以返回一个清理函数。
<input ref={ref => console.log('cleanup')} />
流线型上下文 API
使用 <Context>
直接替换 <Context.Provider>
。
<LanguageContext value="pl-PL">{children}</LanguageContext>
useDeferredValue
初始值
useDeferredValue
hook 现在支持初始值。
const deferredValue = useDeferredValue(value, 'initial')
Hydration Error Diffs(水合错误差异)显示
改进了水合错误的错误日志记录,当发生不匹配时提供详细的差异信息。
Uncaught Error: Hydtation failed
<App>
<span>
+ Client
- Server
ref
作为属性
在函数组件中直接作为 props
传递 refs
。
<MyInput ref={inputRef} />
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。