React 19 New Features Complete Guide: Actions, use(), Server Components, and Compiler Optimizations

前端工程(Updated May 6, 2026)

React 19: A Framework-Level Paradigm Upgrade

React 19 is not just an API update—it's a positioning shift from "library" to "full-stack framework." Server Components, Actions, and Compiler redefine how React applications are written.

Feature Problem Solved Impact Scope
Form Actions Boilerplate code for form submissions All form interactions
use() Hook Conditional data loading Data fetching patterns
Server Components Client bundle size Full architecture
React Compiler Manual memo optimization Performance
ref as prop forwardRef boilerplate Component API
Document Metadata SEO/head management SSR applications

1. Form Actions: Goodbye Form Boilerplate

Traditional Approach

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 ? 'Logging in...' : 'Login'}</button>
      {error && <p>{error}</p>}
    </form>
  );
}

React 19 Approach

async function loginAction(formData) {
  // Executes directly on the server, no manual pending/error management
  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 auto-tracks submission state
function SubmitButton() {
  const { pending } = useActionStatus();
  return <button disabled={pending}>{pending ? 'Logging in...' : 'Login'}</button>;
}

Code reduction: ~60%. No more onSubmit, preventDefault, or manual pending/error state.

useActionState: Managing Form State

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}>Login</button>
      {state?.error && <p className="error">{state.error}</p>}
    </form>
  );
}

2. use() Hook: Conditional Data Loading

use() is React's first Hook that can be called inside conditionals and loops.

Reading Promises

function UserProfile({ userPromise }) {
  // Can be used in conditionals!
  if (showProfile) {
    const user = use(userPromise);
    return <h1>{user.name}</h1>;
  }
  return null;
}

Reading Context

function ThemeToggle() {
  // Previously required useContext, now can use use()
  const theme = use(ThemeContext);
  return <button onClick={toggle}>{theme}</button>;
}

Suspense Integration

function UserPage({ userPromise }) {
  return (
    <Suspense fallback={<Spinner />}>
      <UserProfile userPromise={userPromise} />
    </Suspense>
  );
}

function UserProfile({ userPromise }) {
  const user = use(userPromise);
  return <div>{user.name}</div>;
}

3. Server Components Officially Stable

Server vs Client Components

// Server Component (default)
// - Renders on server, no JS sent to client
// - Can directly access databases, filesystem
// - Cannot use useState, useEffect, event handlers

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';
// - Renders on client (can also SSR)
// - Can use all Hooks
// - Bundled and sent to client

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');
}
// Using Server Action in Client Component
function NewPostForm() {
  return (
    <form action={createPost}>
      <input name="title" />
      <textarea name="content" />
      <button type="submit">Publish</button>
    </form>
  );
}

4. React Compiler: Automatic Performance Optimization

React Compiler (formerly React Forget) auto-inserts memo logic, eliminating the need for manual useMemo, useCallback, and memo.

Before Compilation

function ExpensiveComponent({ items, filter }) {
  // Developer manually optimizes
  const filtered = useMemo(
    () => items.filter(i => i.category === filter),
    [items, filter]
  );

  const handleClick = useCallback((id) => {
    console.log(id);
  }, []);

  return <List items={filtered} onClick={handleClick} />;
}

After Compilation (Auto-Optimized)

function ExpensiveComponent({ items, filter }) {
  // Write directly, compiler auto-memoizes
  const filtered = items.filter(i => i.category === filter);
  const handleClick = (id) => console.log(id);
  return <List items={filtered} onClick={handleClick} />;
}

Enabling the Compiler

// next.config.js
const nextConfig = {
  experimental: {
    reactCompiler: true,  // or 'unstable' for latest features
  },
};

Compiler Limitations

Non-Optimized Scenarios Reason
Mutating incoming props/mutable objects Side effects untraceable
Closures created outside Hooks Unclear lifecycle
Using arguments object Non-standard usage

5. ref as Prop: Goodbye forwardRef

React 18 Approach

const Input = forwardRef((props, ref) => {
  return <input ref={ref} {...props} />;
});

React 19 Approach

function Input({ ref, ...props }) {
  return <input ref={ref} {...props} />;
}

// Usage
<Input ref={inputRef} placeholder="Enter text" />;

6. Document Metadata

React 19 natively supports <title>, <meta>, <link> declared in components:

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 automatically hoists these tags to <head>, with automatic deduplication and replacement across routes.


7. Other Improvements

useOptimistic: Optimistic Updates

function LikeButton({ postId, initialLiked }) {
  const [liked, addOptimisticLike] = useOptimistic(initialLiked);

  async function handleLike() {
    addOptimisticLike(true); // Immediately show like
    await likePost(postId);  // Sync in background
  }

  return <button onClick={handleLike}>{liked ? '❤️' : '🤍'}</button>;
}

useSyncExternalStore Improvements

Supports subscribing to stores where getSnapshot returns different but semantically equivalent values (e.g., cached data fetching).

Full Custom Elements Support

React 19 properly handles Custom Element attributes and events:

<my-custom-element someProp="value" onCustomEvent={handler} />

Migration Checklist

Change Impact Action
forwardRefref prop All components using forwardRef Migrate
useMemo/useCallback Manual memo Gradually remove after enabling Compiler
onSubmitaction Form components Refactor to Actions
useContextuse() Context consumption Optional migration
ref.current.cleanup() ref callback cleanup New pattern
String refs deprecated Legacy code Migrate to callback/object refs

Codemod Tool

npx react-codemod@latest react-19

Automatically handles most breaking changes, including forwardRef migration and string ref replacement.

#React#React 19#Server Components#前端框架