引言
React 19 终于来了!虽然它最初被称为“React 18.3”,但最终以 19 的版本号发布,带来了许多令人兴奋的新特性。本文将通过三个实战场景,带你快速掌握 React 19 的核心新功能:useOptimistic、useActionState 以及 Server Components。
1. useOptimistic:让 UI 即时响应
场景:点赞功能
在传统实现中,用户点击点赞按钮后,需要等待 API 响应才能更新 UI,这会导致明显的延迟。useOptimistic 允许你在 API 请求完成前就乐观地更新 UI,如果请求失败再回滚。
实战代码
import { useOptimistic, useState } from 'react';
function LikeButton({ initialLikes }) {
const [likes, setLikes] = useState(initialLikes);
const [optimisticLikes, addOptimistic] = useOptimistic(
likes,
(state, newLikes) => state + 1
);
const handleLike = async () => {
addOptimistic(1); // 立即乐观更新
try {
const response = await fetch('/api/like', { method: 'POST' });
const data = await response.json();
setLikes(data.likes); // 用真实数据更新
} catch {
// 请求失败,useOptimistic 会自动回滚
}
};
return (
<button onClick={handleLike}>
👍 {optimisticLikes}
</button>
);
}
注意:useOptimistic 的第一个参数是初始状态,第二个参数是更新函数。更新函数接收当前状态和传入的值,返回新的乐观状态。当异步操作完成或失败时,React 会自动根据最终状态调整 UI。
2. useActionState:简化表单处理
场景:登录表单
useActionState 是 React 19 中处理表单的新 Hook,它结合了表单状态管理和异步操作,特别适合与 Server Actions 配合使用。
实战代码
import { useActionState } from 'react';
function LoginForm() {
const [state, formAction, isPending] = useActionState(
async (prevState, formData) => {
const email = formData.get('email');
const password = formData.get('password');
// 模拟 API 调用
const response = await fetch('/api/login', {
method: 'POST',
body: JSON.stringify({ email, password }),
});
if (!response.ok) {
return { error: '登录失败,请检查邮箱和密码' };
}
return { success: true };
},
{ error: null, success: false }
);
return (
<form action={formAction}>
<input name="email" type="email" required />
<input name="password" type="password" required />
<button type="submit" disabled={isPending}>
{isPending ? '登录中...' : '登录'}
</button>
{state.error && <p style={{ color: 'red' }}>{state.error}</p>}
{state.success && <p>登录成功!</p>}
</form>
);
}
💡 使用技巧:useActionState 的第三个返回值 isPending 可以轻松控制按钮的加载状态。注意表单的 action 属性直接绑定到 formAction,不再需要 onSubmit 事件。
3. Server Components:提升性能的新范式
场景:展示文章列表
Server Components 允许你在服务端渲染组件,减少客户端 JavaScript 体积,提升首屏加载速度。
实战代码
首先,确保你的项目支持 React 19 和 Next.js 14+。创建一个 Server Component:
// app/articles/page.jsx (Server Component)
import ArticleCard from './ArticleCard'; // Client Component
export default async function ArticlesPage() {
const res = await fetch('https://api.example.com/articles');
const articles = await res.json();
return (
<div>
<h1>最新文章</h1>
{articles.map(article => (
<ArticleCard key={article.id} article={article} />
))}
</div>
);
}
而 ArticleCard 可以是一个 Client Component(如果需要交互):
// app/articles/ArticleCard.jsx (Client Component)
'use client';
export default function ArticleCard({ article }) {
const [liked, setLiked] = useState(false);
return (
<div>
<h2>{article.title}</h2>
<p>{article.summary}</p>
<button onClick={() => setLiked(!liked)}>
{liked ? '❤️' : '🤍'}
</button>
</div>
);
}
关键点:
- Server Components 默认是服务端渲染,不能使用
useState、useEffect等客户端 Hook。 - 如果需要在组件中使用交互功能,添加
'use client'指令将其标记为 Client Component。 - 混合使用 Server 和 Client Components 可以最大化性能。
常见坑与最佳实践
- useOptimistic 的回滚机制:乐观更新后,如果异步操作失败,React 会自动将状态回滚到上一次正确的值。但要注意,如果你的更新函数有副作用(如更新本地存储),需要手动处理回滚。
- useActionState 的初始值:初始状态对象的结构要与异步函数返回的结构一致,否则可能导致类型错误。
- Server Components 的数据获取:在 Server Components 中直接
await fetch是安全的,因为它只在服务端执行。但要注意错误处理,可以使用try/catch或 React 的error.js边界。
总结
React 19 的这三个新特性显著提升了开发体验和性能:
- useOptimistic 让 UI 即时响应,提升用户感知。
- useActionState 简化了表单状态管理,与 Server Actions 完美配合。
- Server Components 带来了服务端渲染的新范式,减少客户端负担。
下一步,你可以尝试将这些特性整合到现有项目中,或者探索 React 19 的其他新功能,如 use() API 和文档元数据管理。