React 19 use() Hook — Async Functions in Client Components Made Easy
Hello everyone! In today's post, we'll explore the use() hook introduced with React v19. This innovation allows frontend developers to easily use async functions without needing boilerplate code or external libraries (like React Query). Reference Links use() - React Documentation React v19 - React Documentation Next.js v15 - use() Hook Examples Technologies Used Next.js v15 - App Directory React v19 - "use(), Suspense" Tailwindcss What is the use() Hook? As React Frontend developers, with Remix.js and Next.js v14, we were introduced to "React Server Components" and their server-side implementations. In traditional React development, our code and interface components went through a bundling process during build time and were sent to users as a "Client Bundle". These bundles were executed and rendered as JavaScript in the user's browser. This process changed with React Server Components. Now our components are rendered on the server and sent to the client ready to use. This provides: Less JavaScript code running on the client Faster user experience Smaller client bundle sizes Easier error handling on the server side However, using async functions became more complicated in this process. You either needed to use the useEffect hook or external libraries. Thanks to the use() hook introduced with React v19, we can now easily use async functions in Client Components. Demo: Calling Server Action from Client Component As an example, we'll create a "People You May Know" list page for our site users. On this /profiles page, we'll fetch user profiles through a "Server Action" running on our server and display them in the interface using a client component. First, let's write our user fetching function: "use server"; // filepath: /app/profiles/action.ts export async function getLatestUsers() { // 3 seconds delay simulation const wait3Sec = new Promise((resolve) => setTimeout(resolve, 3000)); await wait3Sec; const data = await fetch("https://jsonplaceholder.typicode.com/users"); const users = await data.json(); return users; } After writing our async API call that will run on the server, let's create our page with Next.js and transfer this call from server to client side using React Suspense: "use server"; import { Suspense, use } from "react"; import { getLatestUsers } from "./action"; import { UsersList } from "./users-list.component"; // filepath: /app/profiles/page.tsx export default async function ProfilesPage() { // no need to use await const usersPromise = getLatestUsers(); return ( ); } Notice that we no longer need to use await. With React v19, we can directly pass Promises to the client side. Our Client Component will start populating the screen when the API response arrives. React understands that this call is a Promise and will show the "Suspense Fallback" component until the server response arrives. When the response comes, it will render the component. Now let's create our client-side UsersList component that React will render when the data arrives: "use client"; import { use } from "react"; // filepath: /app/profiles/users-list.component.tsx export function UsersList({ usersPromise }: { usersPromise: Promise }) { // We can directly pass the Promise as a parameter to the use() hook const users = use(usersPromise); return ( Latest Users {users.map((user) => ( {user.id} - {user.username} - {user.email} ))} ); } Demo Image Conclusion With this demo, we explored the use() hook introduced with React v19 that has reached stable release. Thanks to this hook, we can now directly use Promises in Client Components. See you

Hello everyone! In today's post, we'll explore the use()
hook introduced with React v19. This innovation allows frontend developers to easily use async functions without needing boilerplate code or external libraries (like React Query).
Reference Links
Technologies Used
- Next.js v15 - App Directory
- React v19 - "use(), Suspense"
- Tailwindcss
What is the use() Hook?
As React Frontend developers, with Remix.js and Next.js v14, we were introduced to "React Server Components" and their server-side implementations. In traditional React development, our code and interface components went through a bundling process during build time and were sent to users as a "Client Bundle". These bundles were executed and rendered as JavaScript in the user's browser.
This process changed with React Server Components. Now our components are rendered on the server and sent to the client ready to use. This provides:
- Less JavaScript code running on the client
- Faster user experience
- Smaller client bundle sizes
- Easier error handling on the server side
However, using async functions became more complicated in this process. You either needed to use the useEffect
hook or external libraries. Thanks to the use()
hook introduced with React v19, we can now easily use async functions in Client Components.
Demo: Calling Server Action from Client Component
As an example, we'll create a "People You May Know" list page for our site users. On this /profiles
page, we'll fetch user profiles through a "Server Action" running on our server and display them in the interface using a client component.
First, let's write our user fetching function:
"use server";
// filepath: /app/profiles/action.ts
export async function getLatestUsers() {
// 3 seconds delay simulation
const wait3Sec = new Promise((resolve) => setTimeout(resolve, 3000));
await wait3Sec;
const data = await fetch("https://jsonplaceholder.typicode.com/users");
const users = await data.json();
return users;
}
After writing our async API call that will run on the server, let's create our page with Next.js and transfer this call from server to client side using React Suspense:
"use server";
import { Suspense, use } from "react";
import { getLatestUsers } from "./action";
import { UsersList } from "./users-list.component";
// filepath: /app/profiles/page.tsx
export default async function ProfilesPage() {
// no need to use await
const usersPromise = getLatestUsers();
return (
<div>
<Suspense
fallback={
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500" />
}
>
<UsersList usersPromise={usersPromise} />
Suspense>
div>
);
}
Notice that we no longer need to use await
. With React v19, we can directly pass Promises to the client side. Our Client Component will start populating the screen when the API response arrives. React understands that this call is a Promise and will show the "Suspense Fallback" component until the server response arrives. When the response comes, it will render the
component.
Now let's create our client-side UsersList component that React will render when the data arrives:
"use client";
import { use } from "react";
// filepath: /app/profiles/users-list.component.tsx
export function UsersList({ usersPromise }: { usersPromise: Promise<any[]> }) {
// We can directly pass the Promise as a parameter to the use() hook
const users = use(usersPromise);
return (
<div>
<h2 className="text-xl font-semibold mb-3">Latest Usersh2>
<ul className="divide-y divide-gray-100">
{users.map((user) => (
<li key={user.id} className="flex items-center p-3 gap-3">
<div className="flex-1 min-w-0">
{user.id} - {user.username} - {user.email}
div>
li>
))}
ul>
div>
);
}
Demo Image
Conclusion
With this demo, we explored the use()
hook introduced with React v19 that has reached stable release. Thanks to this hook, we can now directly use Promises in Client Components.
See you