React 19Hooks & Patterns
0 views

React 19 Hooks & Patterns Reference

A comprehensive, copy-paste ready reference for React 19's new features. Discover how to use Server Components, the 'use' hook, form actions, and transition enhancements to build modern React applications.

use() Hook

New Hooks

Read the value of a resource like a Promise or context directly in render.

View Official Docs
import { use, Suspense } from "react";

const fetchMessage = async (): Promise<string> => {
  const res = await fetch('/api/message');
  return res.text();
};

const messagePromise = fetchMessage();

function Message() {
  // use() suspends the component until the promise resolves
  const message = use(messagePromise);
  return <p>{message}</p>;
}

export default function App() {
  return (
    <Suspense fallback={<p>Downloading message...</p>}>
      <Message />
    </Suspense>
  );
}

useOptimistic

New Hooks

Optimistically update UI while a background operation (like a mutation) is pending.

View Official Docs
import { useOptimistic, useRef } from "react";

type Message = { text: string; sending: boolean };

export function ChatMessages({ messages, sendMessage }: { messages: Message[], sendMessage: (formData: FormData) => Promise<void> }) {
  const formRef = useRef<HTMLFormElement>(null);
  
  const [optimisticMessages, addOptimisticMessage] = useOptimistic<Message[], string>(
    messages,
    (state, newMessage) => [...state, { text: newMessage, sending: true }]
  );

  async function formAction(formData: FormData) {
    addOptimisticMessage(formData.get("message") as string);
    formRef.current?.reset();
    await sendMessage(formData);
  }

  return (
    <div>
      {optimisticMessages.map((m, i) => (
        <div key={i}>{m.text} {m.sending && <small>(Sending...)</small>}</div>
      ))}
      <form action={formAction} ref={formRef}>
        <input type="text" name="message" required />
        <button type="submit">Send</button>
      </form>
    </div>
  );
}

useFormStatus

Form Hooks

Get status information of the parent <form> without passing props. Must be called in a child component of the form.

View Official Docs
import { useFormStatus } from "react-dom";

function SubmitButton() {
  const { pending, data, method, action } = useFormStatus();
  
  return (
    <button type="submit" disabled={pending} className="bg-blue-500 text-white p-2">
      {pending ? "Submitting..." : "Submit"}
    </button>
  );
}

export function PostForm({ createPost }: { createPost: (data: FormData) => Promise<void> }) {
  return (
    <form action={createPost}>
      <input type="text" name="title" required />
      <SubmitButton />
    </form>
  );
}

useActionState

Form Hooks

Manage state related to a form action (formerly useFormState). Great for validation errors and returned data.

View Official Docs
import { useActionState } from "react";

async function incrementAction(previousState: number, formData: FormData): Promise<number> {
  const incrementBy = Number(formData.get("amount") || 1);
  return previousState + incrementBy;
}

export function Counter() {
  const [state, formAction, isPending] = useActionState<number, FormData>(incrementAction, 0);

  return (
    <form action={formAction}>
      <p>Count: {state}</p>
      <input type="number" name="amount" defaultValue="1" />
      <button type="submit" disabled={isPending}>
        {isPending ? "Incrementing..." : "Increment"}
      </button>
    </form>
  );
}

useTransition (Async Support)

Suspense & Transitions

In React 19, startTransition can now take an async function, allowing you to wait for transitions to complete.

View Official Docs
import { useState, useTransition } from "react";
import { updateName } from "./actions";

export function ProfileForm() {
  const [name, setName] = useState<string>("John");
  const [isPending, startTransition] = useTransition();
  const [error, setError] = useState<string | null>(null);

  const handleSubmit = () => {
    // startTransition accepts async functions in React 19
    startTransition(async () => {
      try {
        const newName = await updateName(name);
        setName(newName);
      } catch (e) {
        setError(e instanceof Error ? e.message : "Failed to update");
      }
    });
  };

  return (
    <div>
      <input value={name} onChange={e => setName(e.target.value)} />
      <button onClick={handleSubmit} disabled={isPending}>
        {isPending ? "Updating..." : "Update"}
      </button>
      {error && <p className="text-red-500">{error}</p>}
    </div>
  );
}

ref as a Prop (No forwardRef)

Classic Hooks Enhanced

React 19 removes the need for forwardRef. You can now pass ref as a regular prop to function components.

View Official Docs
import { useRef, type Ref } from "react";

interface MyInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
  label: string;
  ref?: Ref<HTMLInputElement>; // ref is just a regular prop
}

function MyInput({ label, ref, ...props }: MyInputProps) {
  return (
    <label>
      {label}
      <input ref={ref} {...props} />
    </label>
  );
}

export function Form() {
  const inputRef = useRef<HTMLInputElement>(null);

  return (
    <div>
      <MyInput label="Username" ref={inputRef} />
      <button onClick={() => inputRef.current?.focus()}>
        Focus Input
      </button>
    </div>
  );
}

Directives ('use server' & 'use client')

Server Components

Directives to define module boundaries. 'use client' marks client-side interactive boundaries, 'use server' marks server-only modules or Server Actions.

View Official Docs
// data.ts
'use server'

import { db } from "./db";

// This function can be called from client components (Server Action)
export async function createPost(formData: FormData) {
  const title = formData.get("title") as string;
  await db.posts.insert({ title });
}

// ==========================================

// ClientComponent.tsx
'use client'

import { createPost } from "./data";

export function NewPost() {
  return (
    <form action={createPost}>
      <input name="title" />
      <button type="submit">Create</button>
    </form>
  );
}

React.cache()

Server Components

Cache the results of a function call. Mostly used in Server Components to deduplicate data fetching during a single render pass.

View Official Docs
import { cache } from "react";
import { db } from "./db";

// The cached function will only query the DB once per request, 
// even if called multiple times across different Server Components.
export const getUser = cache(async (id: string) => {
  const user = await db.users.findById(id);
  return user;
});

// Component A
async function ProfileHeader({ id }: { id: string }) {
  const user = await getUser(id);
  return <h1>{user.name}</h1>;
}

// Component B
async function ProfileDetails({ id }: { id: string }) {
  // Reuses the promise/result from the first call!
  const user = await getUser(id);
  return <p>{user.bio}</p>;
}

<form action={...}> Pattern

Form Hooks

React 19 natively supports passing a function to the action prop of a <form>. It automatically prevents default and handles FormData.

View Official Docs
export default function Search() {
  // formData is automatically passed to the action function
  function searchAction(formData: FormData) {
    const query = formData.get("query") as string;
    alert("Searching for: " + query);
  }

  return (
    // No more onSubmit={e => { e.preventDefault(); ... }}
    <form action={searchAction}>
      <input name="query" />
      <button type="submit">Search</button>
    </form>
  );
}

Document Metadata Hoisting

Classic Hooks Enhanced

Render <title>, <meta>, and <link> tags from any component anywhere in the tree. React 19 will automatically hoist them to the <head>.

View Official Docs
function BlogPost({ post }: { post: { title: string, excerpt: string } }) {
  return (
    <article>
      {/* React 19 hoists these tags to document <head> */}
      <title>{post.title} - My Blog</title>
      <meta name="description" content={post.excerpt} />
      <link rel="canonical" href="https://myblog.com/posts/..." />
      
      <h1>{post.title}</h1>
      <p>{post.excerpt}</p>
    </article>
  );
}
Spotlight Hardware & Tools

Handpicked Partner Deals & Gear

Discover top-rated mechanical keyboards, 4K monitors, coding software, and curated developer workstation bundles.

Cite & Link This Resource

Backlink Magnet

Writing a blog post, GitHub README, or docs? Embed a backlink snippet or badge to cite this cheat sheet.

[React 19 Hooks & Patterns Reference](https://devdossier.com/resources/react-19-hooks-patterns) - Interactive Reference & Cheat Sheet via DevDossier
DevDossier Ecosystem20 Platforms

Find Us Everywhere

We publish, stream, and collaborate across every major developer & design platform. Follow along wherever you feel at home.

20+ Platforms
Global Presence
Developer First
Open Ecosystem
Daily Updates
Real-time Content
100% Free
Open Resources
🎁 Partner Rewards⚡ Instant 100+ Points

Earn Microsoft Rewards with DevDossier

Redeem free Xbox Game Pass subscriptions, gift cards, developer tools, and Bing search points directly through Microsoft's official Rewards program.