Next.js Discord

Discord Forum

Server Functions cannot be called during initial render.

Unanswered
ABUL KALAM posted this in #help-forum
Open in Discord
In a client component, I have to fetch an array of cities from the Firebase and display it on the page. I have created a server action that fetches the array from Firebase. I have made a separate function outside the client component that calls the server action and throws Promise. I have called this function it inside the client component. I am using <Suspense /> in the parent component. The <Suspense /> catches the Promise and displays fallback until it is resolved.

Similarly, in another client component, I have to get searchParams and fetch the projects from the Firebase on the basis of it. I am using the same approach here as well.
Here is the code
let projectsData = null,
  projectsError = null,
  projectsPromise = null;

const fetchProjects = () => {
  if (!projectsPromise) {
    projectsPromise = getScreeen3Projects()
      .then(data => {
        projectsData = data;
      })
      .catch(error => {
        projectsError = error;
      });
    throw projectsPromise;
  }
  if (projectsError) {
    throw projectsError;
  }
  if (!projectsData) {
    throw projectsPromise;
  }
  return projectsData;
};

const DesSelStep1Screen2 = () => {
  const allProjects = fetchProjects();
  return (<></>);
}

In both cases, I get the 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.
Now the questions are:
- Should I fetch the data in a useEffect on first render?
- OR should I remove "user server" directive from the function fetching the projects?
- What exactly is the purpose of server actions and should I always use them for CRUD operations?

2 Replies

Spectacled bear
What you can do rather using server action, make a server component like the parent server component, fetch the data, show a loading till it loads using suspense and once it is loaded, pass to a child component which will be a client side component.
@Spectacled bear What you can do rather using server action, make a server component like the parent server component, fetch the data, show a loading till it loads using suspense and once it is loaded, pass to a child component which will be a client side component.
This is actually a multi step form. On the screen 1, the user selects city and cost etc. I store these things in the searchParams and when user clicks Next, I have to fetch the data on the basis of these searchParams and display it to the user.
Both of these screens are on the same route i.e. the same page.js and I am rendering them conditionally on the basis of a screen state (also stored in the searchParams).