返回首页
🎨 前端 / Web
React 19 稳定版特性:Actions、useOptimistic、Server Functions
React 19 引入 Actions / useOptimistic / Server Functions。本文从源码角度解读新特性,及从 18 迁移的注意事项。
React · React 19 · Actions · useOptimistic · Server Functions
📰
今日技术简讯
📰 技术简讯 · 2026-05-06
今日聚合 6 条热门技术内容。
🤖 AI / LLM
1. OpenAI 推出 Skills 协议
- 链接:https://platform.openai.com/skills
- 来源:OpenAI
- 摘要:OpenAI 推出自家 Skills 协议,与 Anthropic MCP 兼容。
🎨 前端 / Web
2. React 19 稳定版特性
- 链接:https://react.dev/blog/react-19
- 来源:React 官方
- 摘要:React 19 稳定版发布,Actions / useOptimistic / Server Functions 全栈支持。
3. Vite 6 推出 Rolldown 引擎
- 链接:https://vite.dev/blog/vite-6
- 来源:Vite
- 摘要:Vite 6.0 引入 Rolldown(Rust 打包),构建速度提升 5 倍。
⚙️ 后端 / 架构
4. PostgreSQL 17.2 发布
- 链接:https://www.postgresql.org/about/news/17-2
- 来源:PostgreSQL
- 摘要:PostgreSQL 17.2 修复 35 个 bug,包含逻辑复制增强。
🚀 独立开发 / OPC
5. Dub.co 推出 Conversions API
- 链接:https://dub.co/conversions
- 来源:Dub
- 摘要:精确追踪联盟营销转化,包括延迟转化和退款。
6. ConvertKit 推出 Newsletter AI
- 链接:https://convertkit.com/ai-newsletter
- 来源:ConvertKit
- 摘要:AI 自动生成 newsletter 草稿,分析读者喜好。
数据来源:掘金 / InfoQ 中文 / HN / GitHub / Dev.to 采集时间:2026-05-06 09:00 (UTC+8)
📝
今日深度文
React 19 稳定版特性:Actions、useOptimistic、Server Functions
一句话结论:React 19 把"全栈"作为一等公民。Actions 让表单处理不再需要 useState + onSubmit + try/catch 模板。
背景
React 19 在 2026 年 Q1 进入稳定版,引入 3 个核心特性:
- Actions:声明式数据变更
- useOptimistic:乐观更新 UI
- Server Functions:服务端代码在客户端透明调用
4 个核心新特性
1. Actions:声明式数据变更
// React 18:手动处理 loading + error + form state
function AddTodo() {
const [text, setText] = useState("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
async function handleSubmit(e) {
e.preventDefault();
setLoading(true);
try {
await fetch("/api/todos", {
method: "POST",
body: JSON.stringify({ text }),
});
setText("");
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}
return (
<form onSubmit={handleSubmit}>
<input value={text} onChange={(e) => setText(e.target.value)} />
{error && <p>{error}</p>}
<button disabled={loading}>
{loading ? "保存中..." : "添加"}
</button>
</form>
);
}
// React 19:用 Action 一行搞定
function AddTodo() {
async function action(formData: FormData) {
"use server";
await db.todos.insert({
text: formData.get("text"),
});
}
return (
<form action={action}>
<input name="text" />
<button>添加</button>
</form>
);
}
代码量减少 80%。
2. useOptimistic:乐观更新
import { useOptimistic } from "react";
function CommentList({ comments }: { comments: Comment[] }) {
const [optimisticComments, addOptimistic] = useOptimistic(
comments,
(state, newComment: Comment) => [...state, newComment]
);
async function add(formData: FormData) {
"use server";
const comment = await db.comments.insert({
text: formData.get("text"),
});
// 立即在 UI 显示(不等服务器返回)
addOptimistic(comment);
}
return (
<div>
{optimisticComments.map((c) => (
<Comment key={c.id} comment={c} />
))}
<form action={add}>
<input name="text" />
<button>提交</button>
</form>
</div>
);
}
用户体验:UI 立即响应,无需等待服务器。
3. Server Functions:服务端透明调用
// 服务端函数(在 'use server' 文件中)
// app/actions.ts
"use server";
export async function getUser(id: string) {
const user = await db.users.findUnique({ where: { id } });
return user;
}
// 客户端调用(自动 RPC)
"use client";
import { getUser } from "@/app/actions";
function UserProfile({ id }: { id: string }) {
const user = use(getUser(id)); // Suspense 集成
return <div>{user.name}</div>;
}
优势:
- 不用写 API endpoint
- 不用 fetch
- 类型安全(自动 RPC)
4. 新 Hooks
// useFormStatus:获取表单提交状态
import { useFormStatus } from "react-dom";
function SubmitButton() {
const { pending } = useFormStatus();
return <button disabled={pending}>{pending ? "提交中..." : "提交"}</button>;
}
// useActionState:管理 action 状态
import { useActionState } from "react";
function Form() {
const [state, action, isPending] = useActionState(serverAction, initialState);
return (
<form action={action}>
<input name="email" />
{state.error && <p>{state.error}</p>}
<button disabled={isPending}>提交</button>
</form>
);
}
// use():读取 Promise / Context
import { use } from "react";
function Profile({ userPromise }: { userPromise: Promise<User> }) {
const user = use(userPromise); // 自动 Suspense
return <div>{user.name}</div>;
}
5 个真实应用场景
场景 1:电商购物车
// 之前:客户端状态 + fetch + 缓存
// 现在:Server Function + useOptimistic
"use server";
export async function addToCart(itemId: string) {
await db.cart.insert({ itemId, userId: getCurrentUser().id });
revalidateTag("cart");
}
// 客户端
function AddToCartButton({ itemId }: { itemId: string }) {
const [, startTransition] = useTransition();
return (
<button onClick={() => startTransition(() => addToCart(itemId))}>
加入购物车
</button>
);
}
场景 2:实时评论
// useOptimistic 让评论立即显示
const [optimistic, addOptimistic] = useOptimistic(comments, ...);
场景 3:表单提交
// useActionState 自动管理表单状态
const [state, action, pending] = useActionState(submitForm, { error: null });
场景 4:SSR 数据获取
// use() 简化 Suspense 集成
const user = use(userPromise);
场景 5:表单验证
// Action 返回错误信息,自动展示
async function action(prev, formData) {
const result = await validateAndSave(formData);
if (!result.success) {
return { error: result.error }; // 自动返回给前端
}
redirect("/success");
}
从 React 18 迁移
Step 1:升级依赖
npm install react@19 react-dom@19
npm install @types/react@19 @types/react-dom@19
Step 2:更新 useTransition
// React 18
const [pending, startTransition] = useTransition();
// React 19:pending 已废弃(用 useFormStatus 替代)
const [, startTransition] = useTransition();
Step 3:Action 改造
// ❌ React 18
const onSubmit = async (e) => { ... };
// ✅ React 19
async function action(formData) { ... }
<form action={action}>
Step 4:处理 StrictMode 警告
// React 19 的 StrictMode 会运行两次 effect
// 确保 effect 是幂等的
useEffect(() => {
fetchData();
}, []);
5 个常见坑
坑 1:Action 不是函数式组件
// ❌ 错误:把 Action 当事件处理器
<button onClick={action}>提交</button>
// ✅ 正确:用在 form action
<form action={action}>
<button type="submit">提交</button>
</form>
坑 2:Server Function 不能传非序列化数据
// ❌ 不能传函数 / Date
await serverAction(() => {}, new Date());
// ✅ 只能传可序列化数据
await serverAction("string", 123, { id: 1 });
坑 3:useOptimistic 必须配 useTransition
// ❌ 单独使用 useOptimistic 没有效果
const [optimistic, addOptimistic] = useOptimistic(...);
// ✅ 必须配 startTransition
const [isPending, startTransition] = useTransition();
startTransition(() => addOptimistic(newComment));
坑 4:Action 的错误必须手动捕获
async function action(formData) {
"use server";
try {
await db.insert(formData);
} catch (err) {
return { error: err.message }; // 返回错误
}
}
坑 5:Suspense 边界必须包裹 use()
<Suspense fallback={<Loading />}>
<Profile userPromise={...} />
</Suspense>
我的看法
React 19 是 React 历史上最重要的版本之一:
- Actions 简化表单处理 80% 代码
- useOptimistic 提升用户体验
- Server Functions 模糊前后端边界
- 新 Hooks 让状态管理更直观
对独立开发者的意义:
- 减少样板代码(更快迭代)
- 更好的 UX(optimistic update)
- 全栈一体化(少学一套 API)
但不要盲目升级:
- 项目还在用 React 16/17 → 优先升 18
- React 18 项目稳定运行 → 等生态成熟再升 19
- 新项目 → 直接 React 19 + Next.js 16
参考
本文基于 React 19.0 稳定版,2026 年 5 月最新文档。
📚 同主题文章
🎨前端 / Web·
Motion + 动画设计实战:现代 Web 交互动效完整指南 2026
Motion(原 Framer Motion)是 2026 年最流行的 React 动画库。本文从 0 到生产级交互动效,含 4 个实战项目 + 性能优化 + AI 动画 + 设计令牌。
MotionFramer Motion动画
🎨前端 / Web·
React 19 实战:从 Server Components 到 Server Actions 完整指南
React 19 是前端框架的"分水岭"——Server Components 让前端从"CSR + API"转向"RSC + Actions"。本文从 0 到生产级 RSC 实战,含 4 个真实项目 + 性能对比。
ReactServer ComponentsServer Actions
🎨前端 / Web·
React Server Components 实战:从 0 到 1 重构电商首页
我们用 React Server Components 把电商首页 LCP 从 4.2s 降到 1.1s,本文分享完整迁移路径和踩坑记录。
ReactRSCNext.js