Skip to content

React 19 Hooks — Zero-to-Hero in One Post

Haikel Fazzani Haikel Fazzani
2025-08-17

React 19 keeps every hook from React 18 and adds six more, so you now have 17 built-in hooks at your fingertips.
Below, each hook is grouped by job, explained in one sentence, and paired with a tiny, real-world TypeScript snippet that runs in any Vite, CRA, or Next.js starter.


🧩 1. State Hooks

HookWhy it exists4-line demo
useStateTrack local mutable stateconst [n,setN]=useState(0);
useReducerHandle complex or multi-step stateconst [s,d]=useReducer(reducer,0);
useActionState (NEW)Built-in state machine for forms & server actions[see below]
// useActionState – contact form with loading & success
import { useActionState } from 'react';

async function send(prev: any, fd: FormData) {
  await fetch('/api/contact', { method:'POST', body: fd });
  return { ok: true };
}

export default function Contact() {
  const [msg, submit] = useActionState(send, {});
  return (
    <form action={submit}>
      <input name="email" required />
      <button disabled={msg.ok}>{msg.ok ? 'Sent ✔' : 'Send'}</button>
    </form>
  );
}

📦 2. Ref Hooks

HookWhy it exists4-line demo
useRefHold a mutable box across rendersconst r=useRef(null);
useImperativeHandleLet parent call child methods via ref[see below]
// useImperativeHandle – parent can call .focus()
import { forwardRef, useRef, useImperativeHandle } from 'react';

const FancyInput = forwardRef<HTMLInputElement>((_, ref) => {
  const inner = useRef<HTMLInputElement>(null);
  useImperativeHandle(ref, () => ({ focus: () => inner.current?.focus() }));
  return <input ref={inner} placeholder="Focus me from parent" />;
});

export default function Parent() {
  const ref = useRef<{ focus(): void }>(null);
  return (
    <>
      <FancyInput ref={ref} />
      <button onClick={() => ref.current?.focus()}>Focus</button>
    </>
  );
}

⚡ Effect & Lifecycle Hooks

HookWhy it exists4-line demo
useEffectRun side-effects after paintuseEffect(()=>console.log('mount'),[]);
useLayoutEffectRun synchronously before paintuseLayoutEffect(()=>measure(),[dep]);
useInsertionEffect (NEW)Inject global styles/scripts before paint[see below]
// useInsertionEffect – add CSS-in-JS without FOUC
import { useInsertionEffect } from 'react';

export default function Button({ color }: { color: string }) {
  useInsertionEffect(() => {
    const style = document.createElement('style');
    style.innerHTML = `.btn-${color}{background:${color};}`;
    document.head.append(style);
    return () => style.remove();
  }, [color]);
  return <button className={`btn-${color}`}>Click</button>;
}

🧪 Transition & Defer Hooks

HookWhy it exists4-line demo
useTransitionKeep UI responsive during heavy updates[see below]
useDeferredValueDefer expensive child renders[see below]
// useTransition – switch tab without freezing UI
import { useState, useTransition } from 'react';

export default function Tabs() {
  const [tab, setTab] = useState('home');
  const [pending, start] = useTransition();
  return (
    <>
      <button onClick={() => start(() => setTab('settings'))}>
        Settings
      </button>
      {pending && <span>Loading…</span>}
      {tab === 'settings' && <h2>Settings ⚙️</h2>}
    </>
  );
}
// useDeferredValue – search stays fast while 10 k rows render
import { useState, useDeferredValue, memo } from 'react';

export default function App() {
  const [text, setText] = useState('');
  const deferred = useDeferredValue(text);
  return (
    <>
      <input value={text} onChange={e => setText(e.target.value)} />
      <BigList filter={deferred} />
    </>
  );
}

const BigList = memo(({ filter }: { filter: string }) => (
  <ul>
    {Array.from({ length: 10000 }, (_, i) => `Item ${i}`)
      .filter(it => it.includes(filter))
      .map(it => <li key={it}>{it}</li>)}
  </ul>
));

📝 Form Hooks (NEW)

HookWhy it exists4-line demo
useFormStateCentralised form state[state,action]=useFormState(fn,{});
useFormStatusKnow if any parent form is submitting[see below]
// useFormStatus – reusable SubmitButton
import { useFormStatus } from 'react-dom';

export function SubmitButton() {
  const { pending } = useFormStatus();
  return <button disabled={pending}>{pending ? 'Saving…' : 'Save'}</button>;
}

🎭 Optimistic UI Hook (NEW)

HookWhy it exists4-line demo
useOptimisticShow instant result, roll back on error[see below]
// useOptimistic – like counter with instant +1, rollback on fail
import { useOptimistic, useState } from 'react';

export default function Like({ id, initial }: { id: string; initial: number }) {
  const [likes, setLikes] = useState(initial);
  const [opt, add] = useOptimistic(likes, l => l + 1);

  async function like() {
    add();
    try {
      await fetch(`/api/like/${id}`, { method:'POST' });
      setLikes(l => l + 1);
    } catch { /* auto-rollback */ }
  }

  return <button onClick={like}>{opt} ❤️</button>;
}

🌐 Promise Hook (NEW)

HookWhy it exists4-line demo
useAwait promises inside components[see below]
// use() – fetch without useEffect
import { use } from 'react';

async function getUser(id: string) {
  const res = await fetch(`/api/user/${id}`);
  return res.json();
}

export default function Profile({ id }: { id: string }) {
  const user = use(getUser(id));
  return <h1>Hi {user.name}</h1>;
}

🔄 Memoization Hooks

HookWhy it exists4-line demo
useMemoCache expensive valuesconst m=useMemo(()=>heavy(v),[v]);
useCallbackCache function referencesconst cb=useCallback(fn,[dep]);

🧩 Context Hook

HookWhy it exists4-line demo
useContextConsume context valuesconst theme=useContext(ThemeCtx);

🪝 Debug Hook

HookWhy it exists4-line demo
useDebugValueLabel custom hooks in DevToolsuseDebugValue(Count:${count});

✅ TL;DR

CategoryHooks
StateuseState, useReducer, useActionState
RefuseRef, useImperativeHandle
EffectuseEffect, useLayoutEffect, useInsertionEffect
TransitionuseTransition, useDeferredValue
Form & OptimisticuseFormState, useFormStatus, useOptimistic
Promiseuse
MemoizationuseMemo, useCallback
ContextuseContext
DebuguseDebugValue

React 19 hooks useActionState example useOptimistic React useTransition tutorial useDeferredValue guide useInsertionEffect React use hook React 19 form hooks React 19 best practices TypeScript React hooks

More Insights.