The new hooks with React 19.
useFormState:
allows you to access the return value of an action the last time a form was submitted. It is useful for handling confirmations or error messages based on the response of a form action.import { useFormState } from 'react-dom'; function MyFormComponent() { const [state, formAction] = useFormState(async (formData) => { // Simulate a form submission const response = await fetch('/api/submit', { method: 'POST', body: JSON.stringify(formData), }); return response.json(); }); return ( <form action={formAction}> <input name="username" /> <button type="submit">Submit</button> {state.pending && <p>Submitting...</p>} {state.data && <p>Form submitted successfully!</p>} </form> ); }useFormStatus:
allows you to know if a form is being sent or if it has been sent successfully. Returns an object with properties such as pending, data, method, and action.import { useFormStatus } from 'react-dom'; function MyFormComponent() { const formStatus = useFormStatus(); return ( <form> <input name="username" /> <button type="submit">Submit</button> {formStatus.pending && <p>Submitting...</p>} {formStatus.success && <p>Form submitted successfully!</p>} </form> ); }useOptimistic:
Allows you to optimistically update the UI while an action is being dispatched. This improves the user experience by showing immediate changes before the asynchronous operation is completed.import { useOptimistic } from 'react-dom'; function MyComponent() { const [optimisticState, updateOptimistic] = useOptimistic(initialState); const handleClick = () => { updateOptimistic((prev) => ({ ...prev, count: prev.count + 1 })); // Simulate an async operation fetch('/api/update', { method: 'POST', body: JSON.stringify({ count: optimisticState.count }), }); }; return ( <div> <p>Count: {optimisticState.count}</p> <button onClick={handleClick}>Increment</button> </div> ); }useTransition:
this hook was already available in React 18.2, now in React 19 it is possible to pass an asynchronous function to startTransition, which React will wait to start the transition. Useful for operations such as sending data via AJAX calls.import { useTransition } from 'react-dom'; function MyComponent() { const [isPending, startTransition] = useTransition(); const handleClick = () => { startTransition(async () => { await fetch('/api/update', { method: 'POST', body: JSON.stringify({ data: 'new data' }), }); }); }; return ( <div> <button onClick={handleClick}>Update Data</button> {isPending && <p>Loading...</p>} </div> ); }use:
A powerful new hook that can be used inside loops and conditions, making it easier to manage contexts and fetching data.import { use } from 'react-dom'; function MyComponent() { const data = use(fetch('/api/data').then(res => res.json())); return ( <div> <p>Data: {data}</p> </div> ); }