React 19 Beta: A first insight
It took over two years from the React 18.0 release to the React 19 beta, but on April 25, 2024, the time had finally come: Meta Platforms officially launched the React 19 Beta presented.
ImportantThis beta release is intended for library developers to prepare for React 19. App developers should update to version 18.3.0 and wait for the stable version of React 19.
New features and improvements
useTransition
A common scenario in the frontend is the submission of a form that requires a certain amount of time to be processed in the API. During this time, we display a "pending" status, for example by graying out the submit button. If the processing is successful, we forward the user; if there is an error, we display an error message.
In React 18, this "pending" state had to be set manually with useState must be implemented. This could cause problems with several asynchronous calls and lead to an inconsistent status.
function UpdateName() {
const [name, setName] = useState("");
const [error, setError] = useState(null);
const [isPending, setIsPending] = useState(false);
const handleSubmit = async () => {
setIsPending(true);
const error = await updateName(name);
setIsPending(false);
if (error) {
setError(error);
return;
}
redirect("/path");
};
return (
<div>
<input value={name} onChange={(event) => setName(event.target.value)} />
<button onClick={handleSubmit} disabled={isPending}>
Update
</button>
{error && <p>{error}</p>}
</div>
);
}
React 19 adds support for asynchronous functions in transitions. Pending states, error messages and other updates are processed automatically. For this you can useTransition use. This requires the status isPending immediately on trueexecutes the API call and sets isPending again after completion false. This ensures that all changes are displayed consistently and responsively in the front end.
function UpdateName() {
const [name, setName] = useState("");
const [error, setError] = useState(null);
const [isPending, startTransition] = useTransition();
const handleSubmit = () => {
startTransition(async () => {
const error = await updateName(name);
if (error) {
setError(error);
return;
}
redirect("/path");
})
};
return (
<div>
<input value={name} onChange={(event) => setName(event.target.value)} />
<button onClick={handleSubmit} disabled={isPending}>
Update
</button>
{error && <p>{error}</p>}
</div>
);
}
useActionState
The new useActionState Hook is specially designed for use with <form> thought. In React 19, the new actions are also integrated into the <form> Feature from react-dom and can be used there.
Example: A form that changes the user's name. When "Submit" is clicked, the request is processed, the button is grayed out and, if successful, the new name is displayed.
function UpdateName() {
const [state, formAction, pending] = useActionState(
async (prevState, formData) => {
const {error, newName} = await updateName(formData.get('name'));
if (error) {
return {error, name: prevState.name};
}
return {error: null, name: newName};
},
{error: null, name: ''},
);
return (
<form action={formAction}>
{state.name && <div>Current name: {state.name}</div>}
<input name="name" placeholder="New name" />
<button type="submit" disabled={pending}>
submit
</button>
<div>{state.error}</div>
</form>
);
}
useActionState returns three parameters:
pending(boolean): Specifies the state of the API request.formAction: Callback to the<form>stateContains the most recent return values from the API request.
We pass 2 parameters to useActionState(fn, initialState):
fn: The function that is called.initialStateThe initial value that the state should have.
In our example, the updateName function, the API call is executed and the name is returned. If the request is successful, the new name is set in the state. In the event of an error prevState.name in the state and added an error message. We now have the last valid name in our output.
useFormStatus
useFormStatus reads the status of the as if the form is a context provider.
useOptimistic
With useOptimistic we can show the user what the result of an API call will look like while it is still being processed.
New API: use
React 19 offers a new way to render resources. use waits until the resource is available (or the promise is resolved) before continuing. In the following example, the comments are only displayed as soon as they are actually available.
import {use} from 'react';
function Comments({commentsPromise}) {
// `use` will suspend until the promise resolves.
const comments = use(commentsPromise);
return comments.map(comment => <p key={comment.id}>{comment}</p>);
}
function Page({commentsPromise}) {
// When `use` suspends in Comments,
// this Suspense boundary will be shown.
return (
<Suspense fallback={<div>Loading...</div>}>
<Comments commentsPromise={commentsPromise} />
</Suspense>
)
}
The use API is still under development. There are still open issues, such as error handling and various usage options.
React Server Components (RSC)
Normally, components are rendered on the client side (CSR), i.e. in the user's browser. With the new React Server Components (RSC), React 19 offers the option of rendering components directly on the server side (SSR). The biggest advantage is that loading times can be extremely reduced. The server takes over the rendering of the component and only sends the rendered component as HTML to the client at the end. The disadvantage is that this component can no longer be re-rendered.
Further improvements
React 19 offers even more improvements, which you can find in the official React 19 Blog can read!
Conclusion
The innovations in React 19 could be a game changer in React development. The React Server Components can make future React applications even more efficient, and the new hooks simplify development considerably.
Unfortunately, there is no release date for React 19 yet.
Sources:
- https://react.dev/blog/2024/04/25/react-19
- https://medium.com/@nduisekeyev/react-19-everything-you-need-to-know-d9058ede5990
- https://www.telerik.com/blogs/current-state-react-server-components-guide-perplexed
- https://www.youtube.com/watch?v=sFeu_aK8cB8
- https://www.youtube.com/watch?v=eQCI4JBWoE8


