I'm currently developing a Next.js 14 application that utilizes ShadCN for UI components and TanStack Query for data fetching. The main screen of the app features a Tabs component that enables users to switch between different sections. One of these sections includes an async server component responsible for making a fetch request to retrieve and display a list of elements.
The Issue:
Upon initial loading of the app, the server component is set as the default tab. However, when I switch to another tab and then return to the server component tab, it starts to continuously make fetch requests in a loop, eventually leading to a crash of the application. Following the crash, the error message "Error: async/await is not yet supported in Client Components, only Server Components..." is displayed.
I attempted to manage the rendering of tabs based on the state of the Tabs selection rather than letting the Tabs component handle it naturally. This approach allowed me to navigate to the second tab successfully, but upon returning to the original main tab, the same looping issue occurred.
Code for the server component and a commented-out definition of the fetching function
import { getCandidates } from "@api";
import { TabsContent } from "@components";
// const url = process.env.NEXT_PUBLIC_API_URL;
// export const getCandidates = async (): Promise<Candidate[]> => {
// const response = await fetch(`${url}/v1/candidates`, { method: "GET" });
// return response.json();
// };
export default async function CandidatesContent() {
// const cand = await fetch(`${url}/v1/candidates`, { method: "GET" });
const candidates = await getCandidates();
console.log(candidates);
return (
<TabsContent value="candidates">
<div>
{candidates.map((candidate) => (
<p key={candidate.id}>{candidate.name}</p>
))}
</div>
</TabsContent>
);
}
Main page containing the Tabs
"use client";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components";
import CandidatesContent from "@/components/candidatesContent/CandidatesContent";
import { useState } from "react";
export default function Home() {
const [activeTab, setActiveTab] = useState("candidates");
return (
<main className="container mx-auto py-4 px-6">
<Tabs value={activeTab} onValueChange={setActiveTab} className="">
<div className="flex justify-center">
<TabsList>
<TabsTrigger value="candidates">Candidates</TabsTrigger>
<TabsTrigger value="results">Results</TabsTrigger>
</TabsList>
</div>
<CandidatesContent />
<TabsContent value="results">
<div>results</div>
</TabsContent>
{/* {activeTab === "candidates" && <CandidatesContent />} */}
{/* {activeTab === "results" && (
<TabsContent value="results">
<div>results</div>
</TabsContent>
)} */}
</Tabs>
</main>
);
}
Query: How can I prevent the server component from continuously re-rendering as it currently does? And what is causing this behavior?