React 19 新特性完全指南:Actions、use()、Server Components 与编译器优化
前端工程(更新于 2026年5月6日)
React 19:框架级的范式升级
React 19 不只是 API 更新,而是从"库"到"全栈框架"的定位转变。Server Components、Actions、Compiler 三大特性重新定义了 React 应用的写法。
| 特性 | 解决的问题 | 影响范围 |
|---|---|---|
| Form Actions | 表单提交的样板代码 | 所有表单交互 |
| use() Hook | 条件式数据加载 | 数据获取模式 |
| Server Components | 客户端包体积 | 全架构 |
| React Compiler | 手动 memo 优化 | 性能 |
| ref as prop | forwardRef 样板代码 | 组件 API |
| Document Metadata | SEO/head 管理 | SSR 应用 |
一、Form Actions:告别表单样板代码
传统写法
function LoginForm() {
const [pending, setPending] = useState(false);
const [error, setError] = useState(null);
async function handleSubmit(e) {
e.preventDefault();
setPending(true);
setError(null);
try {
const formData = new FormData(e.target);
await login(formData.get('email'), formData.get('password'));
} catch (err) {
setError(err.message);
} finally {
setPending(false);
}
}
return (
<form onSubmit={handleSubmit}>
<input name="email" type="email" />
<input name="password" type="password" />
<button disabled={pending}>{pending ? '登录中...' : '登录'}</button>
{error && <p>{error}</p>}
</form>
);
}
React 19 写法
async function loginAction(formData) {
// 直接在 Server 上执行,无需手动管理 pending/error
await login(formData.get('email'), formData.get('password'));
}
function LoginForm() {
return (
<form action={loginAction}>
<input name="email" type="email" />
<input name="password" type="password" />
<SubmitButton />
</form>
);
}
// useActionStatus 自动追踪提交状态
function SubmitButton() {
const { pending } = useActionStatus();
return <button disabled={pending}>{pending ? '登录中...' : '登录'}</button>;
}
减少代码量:约 60%。不再需要 onSubmit、preventDefault、手动 pending/error 状态。
useActionState:管理表单状态
function LoginForm() {
const [state, formAction, isPending] = useActionState(
async (prevState, formData) => {
try {
await login(formData.get('email'), formData.get('password'));
return { success: true };
} catch (err) {
return { error: err.message };
}
},
null
);
return (
<form action={formAction}>
<input name="email" type="email" />
<input name="password" type="password" />
<button disabled={isPending}>登录</button>
{state?.error && <p className="error">{state.error}</p>}
</form>
);
}
二、use() Hook:条件式数据加载
use() 是 React 第一个可以在条件语句和循环中调用的 Hook。
读取 Promise
function UserProfile({ userPromise }) {
// 可以在条件中使用!
if (showProfile) {
const user = use(userPromise);
return <h1>{user.name}</h1>;
}
return null;
}
读取 Context
function ThemeToggle() {
// 之前必须用 useContext,现在可以用 use
const theme = use(ThemeContext);
return <button onClick={toggle}>{theme}</button>;
}
Suspense 集成
function UserPage({ userPromise }) {
return (
<Suspense fallback={<Spinner />}>
<UserProfile userPromise={userPromise} />
</Suspense>
);
}
function UserProfile({ userPromise }) {
const user = use(userPromise);
return <div>{user.name}</div>;
}
三、Server Components 正式稳定
Server vs Client 组件
// Server Component(默认)
// - 在服务端渲染,不发送 JS 到客户端
// - 可以直接访问数据库、文件系统
// - 不能使用 useState、useEffect、事件处理
async function BlogList() {
const posts = await db.query('SELECT * FROM posts');
return (
<ul>
{posts.map(post => (
<li key={post.id}>
<h2>{post.title}</h2>
<LikeButton postId={post.id} /> {/* Client Component */}
</li>
))}
</ul>
);
}
// Client Component
'use client';
// - 在客户端渲染(也可 SSR)
// - 可以使用所有 Hook
// - 打包发送到客户端
function LikeButton({ postId }) {
const [liked, setLiked] = useState(false);
return <button onClick={() => setLiked(!liked)}>❤️</button>;
}
Server Actions
'use server';
async function createPost(formData) {
const title = formData.get('title');
const content = formData.get('content');
await db.insert('posts', { title, content });
revalidatePath('/blog');
}
// Client 组件中使用 Server Action
function NewPostForm() {
return (
<form action={createPost}>
<input name="title" />
<textarea name="content" />
<button type="submit">发布</button>
</form>
);
}
四、React Compiler:自动性能优化
React Compiler(原 React Forget)自动插入 memo 逻辑,开发者不再需要手动使用 useMemo、useCallback、memo。
编译前
function ExpensiveComponent({ items, filter }) {
// 开发者手动优化
const filtered = useMemo(
() => items.filter(i => i.category === filter),
[items, filter]
);
const handleClick = useCallback((id) => {
console.log(id);
}, []);
return <List items={filtered} onClick={handleClick} />;
}
编译后(自动优化)
function ExpensiveComponent({ items, filter }) {
// 直接写,编译器自动 memoize
const filtered = items.filter(i => i.category === filter);
const handleClick = (id) => console.log(id);
return <List items={filtered} onClick={handleClick} />;
}
启用 Compiler
// next.config.js
const nextConfig = {
experimental: {
reactCompiler: true, // 或 'unstable' 获取最新特性
},
};
Compiler 的限制
| 不自动优化的场景 | 原因 |
|---|---|
| 修改传入的 props/mutable 对象 | 副作用无法追踪 |
| 在 Hook 外部创建的闭包 | 生命周期不明确 |
使用 arguments 对象 |
非标准用法 |
五、ref 作为 prop:告别 forwardRef
React 18 写法
const Input = forwardRef((props, ref) => {
return <input ref={ref} {...props} />;
});
React 19 写法
function Input({ ref, ...props }) {
return <input ref={ref} {...props} />;
}
// 使用
<Input ref={inputRef} placeholder="请输入" />;
六、Document Metadata
React 19 原生支持 <title>、<meta>、<link> 在组件中声明:
function BlogPost({ post }) {
return (
<>
<title>{post.title}</title>
<meta name="description" content={post.excerpt} />
<link rel="canonical" href={`https://example.com/blog/${post.slug}`} />
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
</article>
</>
);
}
React 自动将这些标签提升到 <head> 中,不同路由的 metadata 自动去重替换。
七、其他改进
useOptimistic:乐观更新
function LikeButton({ postId, initialLiked }) {
const [liked, addOptimisticLike] = useOptimistic(initialLiked);
async function handleLike() {
addOptimisticLike(true); // 立即显示点赞
await likePost(postId); // 后台同步
}
return <button onClick={handleLike}>{liked ? '❤️' : '🤍'}</button>;
}
useSyncExternalStore 改进
支持订阅 getSnapshot 返回不同值但语义等价的 store(如带缓存的数据获取)。
Custom Elements 完整支持
React 19 正确处理 Custom Elements 的属性和事件:
<my-custom-element someProp="value" onCustomEvent={handler} />
迁移清单
| 变更 | 影响 | 行动 |
|---|---|---|
forwardRef → ref prop |
所有使用 forwardRef 的组件 | 移极迁移 |
useMemo/useCallback |
手动 memo | 启用 Compiler 后逐步移除 |
onSubmit → action |
表单组件 | 重构为 Actions |
useContext → use() |
Context 消费 | 可选迁移 |
ref.current.cleanup() |
ref callback 清理 | 新模式 |
| 字符串 ref 废弃 | 旧代码 | 迁移为 callback/object ref |
Codemod 工具
npx react-codemod@latest react-19
自动处理大部分 Breaking Changes,包括 forwardRef 迁移、字符串 ref 替换等。
#React#React 19#Server Components#前端框架