DevLog
ReactTypeScript

React 19 新特性全解析

2025-12-15·12

React 19 带来了什么?

React 19 是 React 历史上最重要的版本之一,引入了全新的并发特性和开发体验改进。

Actions — 异步状态管理新范式

在 React 19 之前,处理异步操作需要手动管理 loadingerror 等状态。Actions 将这一切自动化:

function UpdateName() {

const [error, submitAction, isPending] = useActionState(

async (prevState, formData) => {

const error = await updateName(formData.get("name"));

if (error) return error;

redirect("/path");

return null;

},

null,

);

return (

<form action={submitAction}>

<input type="text" name="name" />

<button disabled={isPending}>Update</button>

{error && <p>{error}</p>}

</form>

);

}

use() Hook — 在渲染中读取资源

新的 use() API 允许你在渲染阶段直接读取 Promise 或 Context:

import { use } from 'react';

function Comments({ commentsPromise }) {

// use() will suspend until the promise resolves

const comments = use(commentsPromise);

return comments.map(comment => <p key={comment.id}>{comment}</p>);

}

新的 Ref 传递方式

函数组件现在可以直接接受 ref 作为 prop,无需 forwardRef

function MyInput({ placeholder, ref }) {

return <input placeholder={placeholder} ref={ref} />

}

// 使用

<MyInput ref={ref} />

Document Metadata 支持

可以在组件中直接渲染 </code>、<code><meta></code> 等标签:</p> <pre><code>function BlogPost({ post }) { <p>return (</p> <p><article></p> <p><h1>{post.title}</h1></p> <p><title>{post.title}</title></p> <p><meta name="author" content="Author Name" /></p> <p><p>{post.content}</p></p> <p></article></p> <p>);</p> <p>}</code></pre></p> <h2>升级建议</h2> <p>React 19 的升级相对平滑,官方提供了 codemod 工具帮助自动迁移。建议先在非关键路径试验新特性,逐步推广到整个项目。</p> <h2>总结</h2> <p>React 19 标志着 React 开发体验的重大飞跃,Actions、use()、Server Components 的成熟让全栈 React 开发变得更加优雅高效。</p></div></article><div class="max-w-3xl mx-auto px-6 pb-16"><a class="inline-flex items-center gap-2 text-sm font-medium text-gray-600 hover:text-gray-900 transition-colors" href="/"><span aria-hidden="true">←</span>返回文章列表</a></div></main><!--$--><!--/$--><section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false"></section><script src="/_next/static/chunks/c54ea77f8bd9bd39.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[95245,[\"/_next/static/chunks/7ce5475dcb51590b.js\",\"/_next/static/chunks/2922a1fe2ba6032e.js\"],\"ThemeProvider\"]\n3:I[23158,[\"/_next/static/chunks/7ce5475dcb51590b.js\",\"/_next/static/chunks/2922a1fe2ba6032e.js\"],\"default\"]\n4:I[3097,[\"/_next/static/chunks/33074d3ff5d0cd2d.js\",\"/_next/static/chunks/c4d90098b4abc498.js\"],\"default\"]\n5:I[99299,[\"/_next/static/chunks/33074d3ff5d0cd2d.js\",\"/_next/static/chunks/c4d90098b4abc498.js\"],\"default\"]\n6:I[37215,[\"/_next/static/chunks/7ce5475dcb51590b.js\",\"/_next/static/chunks/2922a1fe2ba6032e.js\"],\"ThemeSwitcher\"]\n7:I[54219,[\"/_next/static/chunks/7ce5475dcb51590b.js\",\"/_next/static/chunks/2922a1fe2ba6032e.js\"],\"Toaster\"]\n8:I[6287,[\"/_next/static/chunks/7ce5475dcb51590b.js\",\"/_next/static/chunks/2922a1fe2ba6032e.js\"],\"AgentationGuard\"]\na:I[36345,[\"/_next/static/chunks/33074d3ff5d0cd2d.js\",\"/_next/static/chunks/c4d90098b4abc498.js\"],\"OutletBoundary\"]\nb:\"$Sreact.suspense\"\nd:I[36345,[\"/_next/static/chunks/33074d3ff5d0cd2d.js\",\"/_next/static/chunks/c4d90098b4abc498.js\"],\"ViewportBoundary\"]\nf:I[36345,[\"/_next/static/chunks/33074d3ff5d0cd2d.js\",\"/_next/static/chunks/c4d90098b4abc498.js\"],\"MetadataBoundary\"]\n11:I[16153,[],\"default\"]\n:HL[\"/_next/static/chunks/e805e20c0d8c62a6.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"oNtJ-YLjq7SQt7aPWHwWR\",\"c\":[\"\",\"posts\",\"react-19-new-features\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"posts\",{\"children\":[[\"slug\",\"react-19-new-features\",\"d\"],{\"children\":[\"__PAGE__\",{}]}]}]},\"$undefined\",\"$undefined\",true],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/e805e20c0d8c62a6.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/7ce5475dcb51590b.js\",\"async\":true,\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/2922a1fe2ba6032e.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"suppressHydrationWarning\":true,\"children\":[\"$\",\"body\",null,{\"className\":\"antialiased\",\"children\":[\"$\",\"$L2\",null,{\"children\":[[\"$\",\"$L3\",null,{}],[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}],[\"$\",\"$L6\",null,{}],[\"$\",\"$L7\",null,{\"position\":\"top-center\"}],[\"$\",\"$L8\",null,{}]]}]}]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[\"$L9\",null,[\"$\",\"$La\",null,{\"children\":[\"$\",\"$b\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@c\"}]}]]}],{},null,false,false]},null,false,false]},null,false,false]},null,false,false],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$Ld\",null,{\"children\":\"$Le\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$Lf\",null,{\"children\":[\"$\",\"$b\",null,{\"name\":\"Next.Metadata\",\"children\":\"$L10\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$11\",[]],\"S\":true}\n"])</script><script>self.__next_f.push([1,"13:I[99352,[\"/_next/static/chunks/7ce5475dcb51590b.js\",\"/_next/static/chunks/2922a1fe2ba6032e.js\"],\"\"]\n12:Ta26,"])</script><script>self.__next_f.push([1,"\u003ch2\u003eReact 19 带来了什么?\u003c/h2\u003e\n\u003cp\u003eReact 19 是 React 历史上最重要的版本之一,引入了全新的并发特性和开发体验改进。\u003c/p\u003e\n\u003ch3\u003eActions — 异步状态管理新范式\u003c/h3\u003e\n\u003cp\u003e在 React 19 之前,处理异步操作需要手动管理 \u003ccode\u003eloading\u003c/code\u003e、\u003ccode\u003eerror\u003c/code\u003e 等状态。Actions 将这一切自动化:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003efunction UpdateName() {\n\u003cp\u003econst [error, submitAction, isPending] = useActionState(\u003c/p\u003e\n\u003cp\u003easync (prevState, formData) =\u0026gt; {\u003c/p\u003e\n\u003cp\u003econst error = await updateName(formData.get(\u0026quot;name\u0026quot;));\u003c/p\u003e\n\u003cp\u003eif (error) return error;\u003c/p\u003e\n\u003cp\u003eredirect(\u0026quot;/path\u0026quot;);\u003c/p\u003e\n\u003cp\u003ereturn null;\u003c/p\u003e\n\u003cp\u003e},\u003c/p\u003e\n\u003cp\u003enull,\u003c/p\u003e\n\u003cp\u003e);\u003c/p\u003e\n\u003cp\u003ereturn (\u003c/p\u003e\n\u003cp\u003e\u0026lt;form action={submitAction}\u0026gt;\u003c/p\u003e\n\u003cp\u003e\u0026lt;input type=\u0026quot;text\u0026quot; name=\u0026quot;name\u0026quot; /\u0026gt;\u003c/p\u003e\n\u003cp\u003e\u0026lt;button disabled={isPending}\u0026gt;Update\u0026lt;/button\u0026gt;\u003c/p\u003e\n\u003cp\u003e{error \u0026amp;\u0026amp; \u0026lt;p\u0026gt;{error}\u0026lt;/p\u0026gt;}\u003c/p\u003e\n\u003cp\u003e\u0026lt;/form\u0026gt;\u003c/p\u003e\n\u003cp\u003e);\u003c/p\u003e\n\u003cp\u003e}\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\n\u003ch3\u003euse() Hook — 在渲染中读取资源\u003c/h3\u003e\n\u003cp\u003e新的 \u003ccode\u003euse()\u003c/code\u003e API 允许你在渲染阶段直接读取 Promise 或 Context:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eimport { use } from 'react';\n\u003cp\u003efunction Comments({ commentsPromise }) {\u003c/p\u003e\n\u003cp\u003e// use() will suspend until the promise resolves\u003c/p\u003e\n\u003cp\u003econst comments = use(commentsPromise);\u003c/p\u003e\n\u003cp\u003ereturn comments.map(comment =\u0026gt; \u0026lt;p key={comment.id}\u0026gt;{comment}\u0026lt;/p\u0026gt;);\u003c/p\u003e\n\u003cp\u003e}\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\n\u003ch3\u003e新的 Ref 传递方式\u003c/h3\u003e\n\u003cp\u003e函数组件现在可以直接接受 \u003ccode\u003eref\u003c/code\u003e 作为 prop,无需 \u003ccode\u003eforwardRef\u003c/code\u003e:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003efunction MyInput({ placeholder, ref }) {\n\u003cp\u003ereturn \u0026lt;input placeholder={placeholder} ref={ref} /\u0026gt;\u003c/p\u003e\n\u003cp\u003e}\u003c/p\u003e\n\u003cp\u003e// 使用\u003c/p\u003e\n\u003cp\u003e\u0026lt;MyInput ref={ref} /\u0026gt;\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\n\u003ch3\u003eDocument Metadata 支持\u003c/h3\u003e\n\u003cp\u003e可以在组件中直接渲染 \u003ccode\u003e\u003ctitle\u003e\u003c/code\u003e、\u003ccode\u003e\u003cmeta\u003e\u003c/code\u003e 等标签:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003efunction BlogPost({ post }) {\n\u003cp\u003ereturn (\u003c/p\u003e\n\u003cp\u003e\u0026lt;article\u0026gt;\u003c/p\u003e\n\u003cp\u003e\u0026lt;h1\u0026gt;{post.title}\u0026lt;/h1\u0026gt;\u003c/p\u003e\n\u003cp\u003e\u0026lt;title\u0026gt;{post.title}\u0026lt;/title\u0026gt;\u003c/p\u003e\n\u003cp\u003e\u0026lt;meta name=\u0026quot;author\u0026quot; content=\u0026quot;Author Name\u0026quot; /\u0026gt;\u003c/p\u003e\n\u003cp\u003e\u0026lt;p\u0026gt;{post.content}\u0026lt;/p\u0026gt;\u003c/p\u003e\n\u003cp\u003e\u0026lt;/article\u0026gt;\u003c/p\u003e\n\u003cp\u003e);\u003c/p\u003e\n\u003cp\u003e}\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\n\u003ch2\u003e升级建议\u003c/h2\u003e\n\u003cp\u003eReact 19 的升级相对平滑,官方提供了 codemod 工具帮助自动迁移。建议先在非关键路径试验新特性,逐步推广到整个项目。\u003c/p\u003e\n\u003ch2\u003e总结\u003c/h2\u003e\n\u003cp\u003eReact 19 标志着 React 开发体验的重大飞跃,Actions、use()、Server Components 的成熟让全栈 React 开发变得更加优雅高效。\u003c/p\u003e"])</script><script>self.__next_f.push([1,"9:[\"$\",\"main\",null,{\"className\":\"pt-16\",\"children\":[[\"$\",\"div\",null,{\"className\":\"relative flex items-end bg-gradient-to-br from-orange-400 to-pink-500\",\"style\":{\"minHeight\":\"280px\"},\"children\":[[\"$\",\"div\",null,{\"className\":\"absolute inset-0 bg-black/40\"}],[\"$\",\"div\",null,{\"className\":\"relative z-10 w-full max-w-3xl mx-auto px-6 pb-10 pt-12\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex flex-wrap gap-2 mb-4\",\"children\":[[\"$\",\"span\",\"React\",{\"className\":\"text-xs font-medium px-3 py-1 rounded-full bg-white/20 text-white/90 backdrop-blur-sm border border-white/25\",\"children\":\"React\"}],[\"$\",\"span\",\"TypeScript\",{\"className\":\"text-xs font-medium px-3 py-1 rounded-full bg-white/20 text-white/90 backdrop-blur-sm border border-white/25\",\"children\":\"TypeScript\"}]]}],[\"$\",\"h1\",null,{\"className\":\"text-3xl sm:text-4xl font-bold text-white leading-tight mb-4\",\"children\":\"React 19 新特性全解析\"}],[\"$\",\"p\",null,{\"className\":\"text-white/75 text-sm\",\"children\":[\"2025-12-15\",[[\"$\",\"span\",null,{\"className\":\"mx-2\",\"children\":\"·\"}],12]]}]]}]]}],[\"$\",\"article\",null,{\"className\":\"max-w-3xl mx-auto px-6 py-12\",\"children\":[\"$\",\"div\",null,{\"className\":\"prose\",\"dangerouslySetInnerHTML\":{\"__html\":\"$12\"}}]}],[\"$\",\"div\",null,{\"className\":\"max-w-3xl mx-auto px-6 pb-16\",\"children\":[\"$\",\"$L13\",null,{\"href\":\"/\",\"className\":\"inline-flex items-center gap-2 text-sm font-medium text-gray-600 hover:text-gray-900 transition-colors\",\"children\":[\"$L14\",\"返回文章列表\"]}]}]]}]\n"])</script><script>self.__next_f.push([1,"14:[\"$\",\"span\",null,{\"aria-hidden\":true,\"children\":\"←\"}]\n"])</script><script>self.__next_f.push([1,"e:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"15:I[20414,[\"/_next/static/chunks/33074d3ff5d0cd2d.js\",\"/_next/static/chunks/c4d90098b4abc498.js\"],\"IconMark\"]\nc:null\n10:[[\"$\",\"title\",\"0\",{\"children\":\"React 19 新特性全解析\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"记录技术探索、分享开发经验,偶尔聊聊产品与设计。\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.6d5bd336.ico\",\"sizes\":\"32x32\",\"type\":\"image/x-icon\"}],[\"$\",\"$L15\",\"3\",{}]]\n"])</script></body></html>