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 ?? [],
})
}
}}
/>
)}
I think I figured this out after starting the bounty. The answer is hidden in plain sight.
Error: Server Functions cannot be called during initial render.
Server Functions, not to be confused with Server Components. I'm going to go out on a limb and assume that your
getAllClients()
function is in a file with "use server" at the top, making it a Server Action (or Server Function, as its called in the error message).
THAT is what cannot be called during initial render. Server Actions are intended to be called as part of user interactions. A user clicks a button, which calls a server action.
Server actions are special, and result in a network roundtrip. THAT is why React will not let you call them during initial render.
So have the function which fetches data not be a server action, and this should work for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With