I have a client component called CampaignTable. The CampaignTable component expects a columns object to render the columns. Inside my columns object I import a server component called CampaignActions. This is a simple dropdown menu in which I do an api call to get some data and use that data in my popover.
However, because the api call performed in the CampaignActions component, my page becomes very slow and I get an error saying:
Error: Server Functions cannot be called during initial render. This would create a fetch waterfall. Try to use a Server Component to pass data to Client Components instead.
However, to my understanding the component is already a React Server Component. I can solve the issue by removing the async and performing the api call in the top-level page and passing the data down as props such as:
Page > CampaignTable > CampaignActions.
But I wonder why my approach is wrong / causing issues. Because it would be nice if I could just perform the api call in the component that needs it, rather than passing it down.
This is my code
'use client'
import React from "react";
const CampaignTable = (props: CampaignTableProps) => {
const campaignColumns = useMemo(() => (
[
columnHelper.accessor("id", {
header: () => "ID",
cell: info => info.getValue()
}),
columnHelper.display({
id: "socials",
header: () => "Actions",
cell: ({row}) => {
return (
<CampaignActions {...row.original}/>
)
}
}),
]
), [])
return (
<DataTable
data={props.campaigns || []}
columns={campaignColumns}
/>
)}
My CampaignActions code
async function CampaignActions(props: Campaign){
const {data: clients} = await getAllClients().then((res) => res);
return (
<DataTableActions
edit={{
onEdit: async () => {
await openUpdateCampaignModal({
...props,
clients: clients ?? [],
})
}
}}
/>
)}
.then((res) => res)
does nothing; you can do justconst {data: clients} = await getAllClients();
. – Firecrest