Infinite Loop Server Components vs Client
Answered
Californian posted this in #help-forum
CalifornianOP
I have changed code slightly to be more readable for question
Parent Server Component:
Child Component when Client (works fine)
Child Component when Server (infinite loop) - instead of hooks in client (all else same)
Parent Server Component:
{productNames.map((productObj) => {
//some logic
return (
(activeTab === "All" || categories.includes(activeTab)) && (
<motion.div key={`${name}-${activeTab}`}>
{/* @ts-expect-error Server Component */}
<ProductCard productKey={name} />Child Component when Client (works fine)
export default function ProductCard ({ productKey }: { productKey: string }) {
const [product, setProduct] = useState(null);
const loadState = async () => {
const data = await fetchPackage(productKey);
setPackageDetails(data);
}
useEffect(() => {
loadState();
}, [])Child Component when Server (infinite loop) - instead of hooks in client (all else same)
const packageDetails = await fetchPackage(productKey)65 Replies
Giant panda
Apart from the fact that you could just fetch all details directly in the parent component and pass the fully fetched data down instead of fetching like a waterfall are you 140% sure the child component is really not a client component when trying to using async/await directly?
And is
ProductCard marked async in that case?CalifornianOP
"Apart from the fact that you could just fetch all details directly in the parent component and pass the fully fetched data down instead of fetching like a waterfall" -- very very true
Yeah because when I switch to async, it gives an error that requires the {/* @ts-expect-error Server Component */}
Giant panda
That hasn't been required for months now. You haven't updated the typings or TS to 5.2+ it seems
But that is not the cause of infinite loops
Giant panda
They only occur when a client component is marked async
Answer
CalifornianOP
The browser logs show the response
But it keeps getting hit
And its always the first component in the map that keeps getting returned
Although
Now I look again
I see an error
async/await is not yet supported in Client Components, only Server Components.
But I do not have the use-client
Giant panda
Show both files where the components are.
CalifornianOP
I dont think it is the parent, because when the child is marked client it works
so has to be child we should look at right?
will send now
just a bunch of html and consts after
maybe it is one of the libraries?
Giant panda
Wait your nested component in the previous snippet was called
ProductCard. Did you rename it? Also show me the entire parent file.CalifornianOP
Yeah renamed it in question to make it clear because packaege and product im using interchangebly in my code might be confusino
Giant panda
I mean you're blind here then 😛
This IS a client component
CalifornianOP
fml
Giant panda
Especially since you are using
useSearchParamsCalifornianOP
A few things
I dont mark it as use client
Giant panda
Another parent above it is marked as such
use client is not per component, it's one boundary@Giant panda `use client` is not per component, it's one boundary
CalifornianOP
Not sure what you mean by that
Giant panda
Let's say you have a simple tree of components that is one-dimensional and doesn't branch
A -> B -> C -> DIf you use
use client in the file where B is declaredThen
C and D if used within B become client componentsBecause the directive says between
A and B is the server/client boundaryCalifornianOP
Ah ok, I see, but I remember you said we can do the filtering on the server side
Giant panda
Yeah but in your code you are attempting to directly embed a server component into a client component
Make the
PackageGrid a server components and pass the search params from the page into it without using useSearchParamsAnd sort out how you are using
PackageGrid because its parent is a client component for sure if you have no use client directive in the PackageGrid fileCalifornianOP
Yeah the grid is inside page.tsx which is a client component
Giant panda
Yeah never make layouts or pages client components
CalifornianOP
damn ok, why?
oh
All the children will be client i guess
Giant panda
No
Well
In that case actually they do
But you lose metadata capabilities entirely, any magic functions for data fetching and the ability to use async pages
Also layouts which typically don't rerender if not necessary are prone to rerender regardless
CalifornianOP
Hm ok will look into that for sure
Giant panda
The gist with client components is to use them where necessary and in the best case have them be fairly down in the rendering tree as leafs
@Giant panda Make the `PackageGrid` a server components and pass the search params from the page into it without using `useSearchParams`
CalifornianOP
Would I still be able to pass the searchparams into the grid from the page.tsx even if page becomes server compoennt
Giant panda
Yes
CalifornianOP
Everytime I think I have next13 down I get hit with crazy new thing lol but will work on this
Ok thanks for the help again
CalifornianOP
If anyone comes to this in the future:
searchParams (Server version of useSearchParams hook) can only be accessed as a top-level page component parameter.
This should be passed into the child server component (if necessary).
searchParams can be tricky because you do not do a .get like the hook with the name of the query parameter. Instead do searchParams.('whatever') so it will help to add types if you are using TS
This is a really good article:
https://dev.to/peterlidee/using-searchparams-usesearchparams-and-userouter-in-next-13-4623
searchParams (Server version of useSearchParams hook) can only be accessed as a top-level page component parameter.
This should be passed into the child server component (if necessary).
searchParams can be tricky because you do not do a .get like the hook with the name of the query parameter. Instead do searchParams.('whatever') so it will help to add types if you are using TS
This is a really good article:
https://dev.to/peterlidee/using-searchparams-usesearchparams-and-userouter-in-next-13-4623
Giant panda
as of 2023 Oct searchParams (Server version of useSearchParams hook) can only be accessed as a top-level page component parameter.That line makes no sense.
searchParams always existed on the page itselfCalifornianOP
I meant future looking, I would assume/hope they make it accessible to server components down the tree
In which case a lot of the trouble is alleviated, hope that makes sense
Giant panda
That won't be possible just like server components can't access the current path
CalifornianOP
Ah ok well, there you go