The React 19 RC was released on April 25, 2024. It introduces a range of new features set to transform React development. Contrary to popular belief, the React team isn’t only focused on React Server Components and Next.js. The upcoming release emphasizes web primitives and form data being one of those primitives.
Consider this simple example where we are using the useState hook to manage isPending
and data
, message
.
It works fine but there is quite a lot of boilerplate to handle data, isPending, and message states.
React 19 has support for using async functions in transitions to handle pending states, errors, forms, and optimistic updates automatically.
In React 19, functions that trigger transitions are now called actions.
So action is a function that triggers a transition which we can do in multiple ways.
We can create an action using useActionState
.
It makes easy-to-use actions and also gets status updates on
that transition that the action triggers and then sets state based on the returned data.
New client-side hooks coming up in React 19 addresses significant issues related to data mutations and form management, simplifying the handling of pending states, errors, optimistic updates, and sequential requests, which previously required manual intervention.
Let’s look into these new hooks in detail.
1. useActionState hook
useActionState
is a hook that a more streamlined way to handle form actions.
useActionState
accepts 3 argument
- fn: The function to be called when the form is submitted or the button pressed
- initialState: Initial state
- permalink (optional): A string containing the unique page URL that this form modifies.
It returns
- initial state/ or the data returned when the actions is completed
- Action function
- pending state indicator
Using useActionState
, we no longer need a separate data state because it is returned by the hook.
The submit action, which we provide to the hook, receives the current state and form data as arguments by default.
This means we don’t have to manually set the user’s input state; instead, we can directly retrieve it from the form data.
Additionally, the hook provides an isPending
state.
The behavior remains consistent with less boilerplate code.
NOTE: In earlier React Canary versions, this API was part of React DOM and called useFormState
.
2. useFormStatus hook
Building design systems often involves components that rely on data from the surrounding <form>
.
Traditionally, this data is passed down through props, potentially creating a long chain of prop drilling or Context.
To simplify this common scenario, React 19 introduces the new useFormStatus
hook.
The useFormStatus
hook provides an easy way to track the status of form submissions.
It does not take any parameters and returns a status object with the following properties:
- pending: Status of form submission
- data: Form data
- method: HTTP method used for submission (e.g., “POST”)
- action: A reference to the function passed to the action prop on the parent <form>
Things to note:
- The
useFormStatus
hook must be called from a component that is rendered inside a<form>
. - It will not return status information for any
<form>
rendered in that same component or children components.
In this example, useFormStatus
is called in the child component of form
,
so the form status and data are available using the hook.
When the useFormStatus
hook is called inside the component with a form,
pending
is never tracked and it will always be false.
Examples are taken from react.dev
3. useOptimistic hook
The useOptimistic
hook lets us create a smoother user experience for forms.
It allows us to update the interface with the expected outcome immediately after submission,
even before the server confirms the change.
This eliminates the wait for the server’s response, making the app feel more responsive.
Here’s how it works:
We provide the current state and a updateFn
that merges the current state with an optimistic update.
addOptimistic
is called with the optimistic value whenever an action is initiated.
React will call updateFn
and render the optimistic state.
If the action succeeds, the optimistic state becomes the final state. If it fails, React automatically reverts to the original state. This provides a responsive UI without displaying incorrect data.
Here is an example from react.dev.
4. use hook
The use
hook is used to read the value of a resource like a promise or context.
i. Reading promise with use
The use hook simplifies data fetching and working with promises. It allows us to use the result of a promise directly inside our component without extra boilerplate.
The use
hook takes a promise and returns its result.
The use
hook integrates with Suspense and error boundaries.
When we use the use
hook, our component will pause until the provided Promise finishes.
If our component is wrapped in a Suspense component, we’ll see a fallback UI while waiting.
Once the Promise resolves successfully, the fallback disappears,
and the data will be rendered.
However, if the Promise is rejected, the closest Error Boundary’s fallback will be displayed instead.
NOTE: Unlike React Hooks, use
can be called within loops and conditional statements.
ii. Reading context with use
When a context is passed to use, it works similarly to useContext
.
While useContext
must be called at the top level of our component,
use
can be called inside conditionals like if
and loops like for
.
use
is preferred over useContext
because it is more flexible.
Conclusion
React 19 supercharges functional components with new hooks!
These hooks streamline common tasks, making development faster and more enjoyable.
- Smoother User Experience: The
useOptimistic
hook lets us update the UI immediately after a user interacts with a form, even before data is confirmed by the server. This provides instant feedback and keeps users engaged. - Effortless Form Handling: The
useFormStatus
anduseActionState
hooks simplify form management. They track submission status and centralize form state, reducing boilerplate code. - Declarative Data Fetching: The
use
hook integrates with promises and Suspense. This allows us to fetch data cleanly and concisely, minimizing the need for extra code.
Overall, these new hooks benefit developers by:
- Saving Time: They streamline common tasks, reducing development time.
- Promoting Code Reusability: The focus on centralized state management encourages code reuse.
- Building Better UIs: Faster development and a focus on user experience lead to more performant and engaging applications.