This error occurs when you try to define a Client Component as an async function in React or Next.js. Client Components do not support async functions because they run in the browser where async component rendering is not yet supported. Only Server Components can be async, allowing them to await data directly in the component body.
React introduced async Server Components as part of React Server Components (RSC) architecture, allowing components to be async functions that can await promises during rendering. However, this feature is only available for Server Components that run on the server. Client Components, which run in the browser and include interactive features like event handlers and hooks, cannot be async functions. When you mark a component with "use client" directive (making it a Client Component) and also define it as an async function, React or Next.js throws this error because the two features are incompatible. The browser environment does not yet support suspending component rendering while awaiting promises in the same way the server can.
Check if your component uses client-side features like useState, useEffect, event handlers (onClick, onChange), or browser APIs. If it does not use any of these, remove the "use client" directive and keep it as a Server Component where async is allowed.
// If your component looks like this with no client features:
"use client"; // ← Remove this line
async function MyComponent() {
const data = await fetchData();
return <div>{data.title}</div>;
}If your component must be a Client Component (because it uses hooks or event handlers), remove the async keyword from the function definition. Move any data fetching logic to useEffect or use a data fetching library.
// WRONG - Client Component cannot be async
"use client";
async function MyComponent() {
const data = await fetchData();
return <div onClick={handleClick}>{data.title}</div>;
}
// CORRECT - Use useEffect for data fetching
"use client";
import { useState, useEffect } from "react";
function MyComponent() {
const [data, setData] = useState(null);
useEffect(() => {
fetchData().then(setData);
}, []);
return <div onClick={handleClick}>{data?.title}</div>;
}If you need both async data fetching and client-side interactivity, split your component into two: a Server Component that fetches data and a Client Component that handles interactivity. Pass the fetched data as props.
// ServerComponent.tsx (async, no "use client")
async function ServerComponent() {
const data = await fetchData();
return <ClientComponent data={data} />;
}
// ClientComponent.tsx (not async, has "use client")
"use client";
interface Props {
data: DataType;
}
function ClientComponent({ data }: Props) {
const handleClick = () => {
// Client-side logic
};
return <div onClick={handleClick}>{data.title}</div>;
}If you need to call async functions from a Client Component (like form submissions or mutations), use Server Actions. Define the async function with "use server" and call it from your Client Component.
// actions.ts
"use server";
export async function submitForm(formData: FormData) {
const result = await saveToDatabase(formData);
return result;
}
// ClientComponent.tsx
"use client";
import { submitForm } from "./actions";
function ClientComponent() {
const handleSubmit = async (formData: FormData) => {
const result = await submitForm(formData);
// Handle result
};
return <form action={handleSubmit}>...</form>;
}For complex data fetching in Client Components, use libraries like SWR, React Query (TanStack Query), or Apollo Client. These libraries handle caching, revalidation, and loading states automatically.
"use client";
import useSWR from "swr";
function ClientComponent() {
const { data, error, isLoading } = useSWR("/api/data", fetcher);
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error loading data</div>;
return <div onClick={handleClick}>{data.title}</div>;
}In Next.js App Router, all components are Server Components by default. Only add "use client" when absolutely necessary. Review your component tree and ensure you are not unnecessarily marking components as Client Components when they could remain Server Components.
// app/page.tsx (Server Component - can be async)
async function Page() {
const data = await fetchData();
return (
<div>
<ServerContent data={data} />
<InteractiveButton /> {/* This can be a Client Component */}
</div>
);
}The async component restriction exists because React needs to synchronously render Client Components in the browser. When a component is async, React would need to suspend rendering and wait for promises to resolve, which is only supported in Server Components running in Node.js. The React team is exploring ways to support async Client Components in the future, possibly using the use() hook for promise unwrapping. For now, the recommended pattern is to keep your component tree mostly Server Components (async) and only mark the minimal interactive parts as Client Components. This pattern is called "Server Component First" and results in smaller JavaScript bundles sent to the client. In Next.js 13+ with App Router, you can fetch data in layouts and pages (Server Components) and pass it down to Client Components, creating a clean separation of concerns. If you absolutely need async behavior in something that feels like a Client Component, consider using the use() hook with Suspense boundaries, though this is an advanced pattern and may not be necessary for most use cases.
React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
useNavigate() may be used only in the context of a <Router> component.
useNavigate() may be used only in the context of a Router component
Cannot find module or its corresponding type declarations
How to fix "Cannot find module or type declarations" in Vite