#async client component
1 messages · Page 1 of 1 (latest)
Hi @thorn tulip. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
You're encountering an error because React Client Components cannot be async functions. This is a known limitation in React's client-side rendering model.
Why This Error Occurs
When you define an async function as a Client Component (with the 'use client' directive), React cannot properly handle it. This is because React Client Components do not support async functions.
How to Fix It
Here are several approaches to solve this issue:
1. Convert to a Server Component
If possible, the recommended approach is to move your data fetching to a Server Component:
// This works fine as a Server Component (no 'use client' directive)
export default async function Page() {
const data = await fetch('<https://api.example.com/data'>)
const result = await data.json()
return <div>{result.title}</div>
}
2. Use React's use hook with Context
You can pass promises from Server Components to Client Components using context:
First, create a context provider:
'use client'
import { createContext, useContext } from 'react'
export const DataContext = createContext<Promise<any> | null>(null)
export function DataProvider({
children,
dataPromise,
}: {
children: React.ReactNode
dataPromise: Promise<any>
}) {
return (
<DataContext.Provider value={dataPromise}>{children}</DataContext.Provider>
)
}
export function useDataContext() {
const context = useContext(DataContext)
if (!context) {
throw new Error('useDataContext must be used within a DataProvider')
}
return context
}
Then, create the Promise in a Server Component:
import { DataProvider } from './context'
import { DataComponent } from './data-component'
export default function Page() {
const dataPromise = fetch('https://api.example.com/data').then((res) =>
res.json()
)
return (
<DataProvider dataPromise={dataPromise}>
<DataComponent />
</DataProvider>
)
}
Finally, use the `use` hook in your Client Component:
```tsx
'use client'
import { use } from 'react'
import { useDataContext } from './context'
export function DataComponent() {
const dataPromise = useDataContext()
const data = use(dataPromise)
return <div>{data.title}</div>
}
3. Use Client-Side Data Fetching
For client-side data fetching, use hooks like useEffect or libraries like SWR:
'use client'
import { useState, useEffect } from 'react'
export function DataComponent() {
const [data, setData] = useState(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
async function fetchData() {
const res = await fetch('<https://api.example.com/data'>)
const result = await res.json()
setData(result)
setLoading(false)
}
fetchData()
}, [])
if (loading) return <div>Loading...</div>
return <div>{data.title}</div>
}
4. Use Server Actions
If you need to perform async operations from a Client Component, consider using Server Actions:
// actions.ts
'use server'
export async function fetchData() {
const res = await fetch('<https://api.example.com/data'>)
return res.json()
}
// client-component.tsx
'use client'
import { fetchData } from './actions'
import { useState, useEffect } from 'react'
export function ClientComponent() {
const [data, setData] = useState(null)
useEffect(() => {
fetchData().then(setData)
}, [])
if (!data) return <div>Loading...</div>
return <div>{data.title}</div>
}