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%。不再需要 onSubmitpreventDefault、手动 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 逻辑,开发者不再需要手动使用 useMemouseCallbackmemo

编译前

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} />

迁移清单

变更 影响 行动
forwardRefref prop 所有使用 forwardRef 的组件 移极迁移
useMemo/useCallback 手动 memo 启用 Compiler 后逐步移除
onSubmitaction 表单组件 重构为 Actions
useContextuse() 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#前端框架