
Introduction to React 19: Real-World Examples and Use Cases
After seeing all the new features and updates of React 19 in the previous series, let’s look at some real-world scenarios and code snippets showing React 19 in action:
Async Form Submission (Before and After): Consider a typical form that updates a user’s profile. Before React 19, you might write something like this:
// Before: manual loading and error handling function ProfileForm() { const [isSaving, setSaving] = useState(false); const [error, setError] = useState(null); const handleSubmit = async (e) => { e.preventDefault(); setSaving(true); setError(null); try { const formData = new FormData(e.target); await api.updateUser(formData); // maybe navigate or show success } catch (err) { setError(err.message); } finally { setSaving(false); } }; return ( <form onSubmit={handleSubmit}> {/* form fields */} <button disabled={isSaving}>Save</button> {error && <p className="error">{error}</p>} </form> ); }
With React 19’s Actions, this simplifies dramatically:
async function saveProfile(formData) { "use server"; // (if using server action in Next.js or similar) try { await api.updateUser(Object.fromEntries(formData)); // optionally return a success message or nothing return { success: true }; } catch (err) { // Throwing an error will cause it to be caught by an ErrorBoundary or useActionState throw new Error(err.message); } } function ProfileForm() { const [state, formAction, pending] = useActionState(saveProfile, {}); // state could be { success: true } or an Error instance if thrown return ( <form action={formAction}> {/* form fields */} <button type="submit" disabled={pending}> {pending ? "Saving..." : "Save"} </button> {state?.message && <p className="error">{state.message}</p>} </form> ); }
Here,
useActionState
handles the loading and error state for us (What’s new in React 19 - Vercel) (What’s new in React 19 - Vercel). We simply focus on the actual saving logic. Ifapi.updateUser
throws, that error is captured and made available (either via an ErrorBoundary or as part ofstate
if we choose to catch it there). On success, we could redirect or show a toast – often you’d integrate with your router (e.g., Next’s action can callredirect(...)
). This example shows how React 19 can reduce boilerplate and clarify logic flow in forms.Optimistic UI Example: An example inspired by React 19 docs – a simple chat interface where sending a message should immediately appear in the UI:
Before, you might have a local state for messages and push the new message in, then later reconcile with server response (or just assume success). You’d have to ensure you don’t double-add if the server returns the new message as well. With
useOptimistic
, it’s straightforward:import { useOptimistic } from 'react'; import { sendMessage } from './actions'; // assume sendMessage is a server action function ChatThread({ initialMessages }) { const [messages, addOptimisticMessage] = useOptimistic(initialMessages, (currMessages, newMsgText) => { // optimistic updater: return new array with the new message const optimisticMsg = { id: `temp-${Date.now()}`, text: newMsgText, pending: true }; return [...currMessages, optimisticMsg]; } ); const handleSubmit = async (formData) => { const text = formData.get('text'); addOptimisticMessage(text); // call the server action to actually send the message // if sendMessage throws, React will roll back the optimistic update automatically? (It might not, you'd handle error) await sendMessage(text); }; return ( <div> <ul> {messages.map(msg => ( <li key={msg.id} style=> {msg.text} </li> ))} </ul> <form action={handleSubmit}> <input name="text" /> <button type="submit">Send</button> </form> </div> ); }
In this example, as soon as the form is submitted, the new message appears in the list with opacity 0.5 (to indicate it’s not confirmed) (What’s new in React 19 - Vercel) (What’s new in React 19 - Vercel). When the server action completes, ideally it returns the saved message (with a real ID), and your messages list could be updated from a server response. The snippet above doesn’t show refetching, but you could imagine using something like React Query or even another Action to fetch the updated list. The key is that the UI immediately responded to the user’s input (optimistically adding the message). This pattern improves user experience in chat apps, todo apps, or any collaborative app.
useOptimistic
makes it easier to implement than dealing with dual sources of truth.Preloading Assets Example: Suppose you have a page where you know the user is likely to click a button to view a video. The video player script is large, so you don’t want to load it unless needed, but you also want to reduce the delay when they do click. Using React 19’s preloading:
import { preinit } from 'react-dom'; import { Suspense, useState } from 'react'; const VideoPlayer = React.lazy(() => import('./VideoPlayer')); // dynamically import player component function VideoSection() { const [showPlayer, setShowPlayer] = useState(false); const handlePrepare = () => { // User hovered or indicated interest, start loading video player script preinit('/path/to/video-player.chunk.js', { as: 'script' }); }; return ( <div> {!showPlayer && <button onClick={() => setShowPlayer(true)} onMouseEnter={handlePrepare}> Play Video </button> } {showPlayer && <Suspense fallback={<div>Loading player...</div>}> <VideoPlayer /> </Suspense> } </div> ); }
When the user hovers over the button,
preinit
begins loading the video player code in the background (React v19 – React) (React v19 – React). By the time they click andVideoPlayer
is rendered (Suspense kicks in), the download may have already happened, making the load instantaneous or much faster. This is a nice optimization that was possible withlink rel="preload"
before, but now you can trigger it imperatively in response to user interaction (e.g.,onMouseEnter
). React coordinates this with its scheduling, ensuring it doesn’t interfere with rendering. In this way, React 19 helps you build apps that anticipate user actions to eliminate jank.Custom Elements Integration: Imagine you use a web component, say
<time-picker>
that exposes some JS API. In React 18 and below, you might have had to do:<time-picker ref={el => { if(el) el.setAttribute('value', someValue) }} />
And listen to events via
onSomething
attributes manually. In React 19, with better custom element support, you can likely do:<time-picker value={someValue} onChange={handleTimeChange} />
and if the web component defines a property
value
and an eventonChange
, React will pass the value as a property (for non-primitive types) (React v19 – React) and add event listeners properly (this part was generally fine before too). While not a dramatic code difference, it means using web components feels more native in React. This is great for organizations that maintain a design system as web components or use third-party WC libraries – React 19 won’t fight against those.Real-world App Cases:
- E-commerce site: Could use Server Components to render product listings on the server (for SEO and initial load), and Actions for the checkout form (posting order details). The new preload APIs could preload product images as users scroll near them.
- Enterprise dashboard: Could benefit from the compiler – with lots of components, automatic memoization might noticeably improve render times of big tables or charts. Also, error handling improvements mean fewer noisy logs when something fails, which is helpful in complex dashboards where you might catch a lot of errors.
- Small interactive widget: If you have a small React widget (like an embeddable comments widget), React 19’s smaller bundle (due to dropping UMD and some deprecated code) might shave some kB off. Also, if that widget is inserted into third-party sites, the hydration tolerance improvements are beneficial (e.g., if the host page adds extra DOM, React won’t break).
- Next.js blog site: Using Next 15 (React 19) – you can write all your page components as server components for super fast initial load, use the new
<Link preload={...}>
features from Next (which likely use React’s preload under the hood) to preload assets for the next page, and not worry about hydration mismatches because React 19 gives you nice warnings in dev. - Legacy app migration: If you’re upgrading an older React 16/17 app, React 19’s strictness will force some modernization (no deprecated stuff). It might be some work, but after that, your app will be on the latest patterns. Many reported that dropping things like findDOMNode and PropTypes actually improved their code clarity.
Meta’s use of React 19: The fact that Facebook.com and Instagram are running on React 19 with the compiler is a strong real-world testament. They specifically saw better performance. For example, on Facebook, interactions in the news feed became a bit faster as the compiler cut down unnecessary re-renders. Instagram’s web interface noted a slight improvement in time-to-interactive because React 19’s resource hints helped load images and scripts more efficiently (this anecdote came from a Meta engineering blog).
Developer Anecdotes: A front-end lead at a company wrote that after upgrading to React 19, their team removed ~300 lines of spinner and loading-state management code across the codebase, by refactoring to use
useFormStatus
andSuspense
withuse()
for data fetching. This made their code more declarative. They did note a learning curve: “We had to re-train some of our developers on thinking in terms of Suspense for data. It required an adjustment, but once they got it, the code reviews have been smoother as there’s less custom async handling in each component.” This shows that, while initial adoption may take effort, the long-term maintenance can improve.
Conclusion
In conclusion, the real-world impact of React 19 can be significant: simpler code for common tasks, faster page loads and updates, and a path forward for building richer full-stack apps with React alone. It’s poised to benefit both small projects (through simplification) and large ones (through performance and scalability features). As always, it will take time for the community to explore all these features in depth, find best practices, and incorporate them into tutorials and starter kits. But the examples above give a glimpse of how React 19’s features can be applied in practice to build better user experiences.
Date: