--- title: No async Client Component --- > Client components cannot be async functions. ## Why This Error Occurred The error occurs when you try to define a Client Component as an async function. React Client Components [do not support](https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md#why-cant-client-components-be-async-functions) async functions. For example: ```tsx 'use client' // This will cause an error async function ClientComponent() { // ... } ``` ## Possible Ways to Fix It 1. **Convert to a Server Component**: If possible, convert your Client Component to a Server Component. This allows you to use `async`/`await` directly in your component. 2. **Remove the `async` keyword**: If you need to keep it as a Client Component, remove the `async` keyword and handle data fetching differently. 3. **Use React Hooks for data fetching**: Utilize hooks like `useEffect` for client-side data fetching, or use third-party libraries. 4. **Leverage the `use` API with a Context Provider**: Pass promises to child components using context, then resolve them with the `use` API. ### Recommended: Server-side data fetching We recommend fetching data on the server. For example: ```tsx filename="app/page.tsx" export default async function Page() { const data = await fetch('https://api.vercel.app/blog') const posts = await data.json() return ( ) } ``` ### Using `use` with Context Provider Another pattern to explore is using the React `use` API with a Context Provider. This allows you to pass Promises to child components and resolve them using the `use` API . Here's an example: First, let's create a separate file for the context provider: ```tsx filename="app/context.tsx" 'use client' import { createContext, useContext } from 'react' export const BlogContext = createContext | null>(null) export function BlogProvider({ children, blogPromise, }: { children: React.ReactNode blogPromise: Promise }) { return ( {children} ) } export function useBlogContext() { const context = useContext(BlogContext) if (!context) { throw new Error('useBlogContext must be used within a BlogProvider') } return context } ``` Now, let's create the Promise in a Server Component and stream it to the client: ```tsx filename="app/page.tsx" import { BlogProvider } from './context' export default function Page() { const blogPromise = fetch('https://api.vercel.app/blog').then((res) => res.json() ) return ( ) } ``` Here is the blog posts component: ```tsx filename="app/blog-posts.tsx" 'use client' import { use } from 'react' import { useBlogContext } from './context' export function BlogPosts() { const blogPromise = useBlogContext() const posts = use(blogPromise) return
{posts.length} blog posts
} ``` This pattern allows you to start data fetching early and pass the Promise down to child components, which can then use the `use` API to access the data when it's ready. ### Client-side data fetching In scenarios where client fetching is needed, you can call `fetch` in `useEffect` (not recommended), or lean on popular React libraries in the community (such as [SWR](https://swr.vercel.app/) or [React Query](https://tanstack.com/query/latest)) for client fetching. ```tsx filename="app/page.tsx" 'use client' import { useState, useEffect } from 'react' export function Posts() { const [posts, setPosts] = useState(null) useEffect(() => { async function fetchPosts() { const res = await fetch('https://api.vercel.app/blog') const data = await res.json() setPosts(data) } fetchPosts() }, []) if (!posts) return
Loading...
return ( ) } ```