Rendering Server component inside Client
Unanswered
Red carpenter ant posted this in #help-forum
Red carpenter antOP
So, I need to render a card (server component) component inside a client component.
The parent component is a Client component where I'm using states and other client side stuff.
Now I've tried to use the composition pettern to render a server component there. But it is still rendering on the client.
Maybe I am missing something
The parent component is a Client component where I'm using states and other client side stuff.
Now I've tried to use the composition pettern to render a server component there. But it is still rendering on the client.
Maybe I am missing something
49 Replies
American Crow
TempalteDirecotryTemplatePage is a server component and templates is serializable ?
Asiatic Lion
I don't think it's possible. Literally, parent component is client side one. it means it will be rendered on the browser. 

@Red carpenter ant So, I need to render a card (server component) component inside a client component.
The parent component is a Client component where I'm using states and other client side stuff.
Now I've tried to use the composition pettern to render a server component there. But it is still rendering on the client.
Maybe I am missing something
I think its the xy problem. https://xyproblem.info/
American Crow
Here is a quick working example:
page.tsx
counter.client.tsx
love.server.tsx
page.tsx
import Counter from "./counter.client"
import Love from "./love.server"
export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<h1 className="text-6xl font-bold">Hello From Page (Server)!</h1>
<Counter>
<Love />
</Counter>
</main>
)
}counter.client.tsx
"use client"
import { useState } from "react"
type Props = {
children: React.ReactNode // A Server Component
}
export default function Counter({ children }: Props) {
const [count, setCount] = useState(0)
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
{/* This is just a indicator where to render the server component child. */}
{children}
{/* The client component does not know anything about the server component. */}
</div>
)
}love.server.tsx
export default function Love() {
// Don't use this check in production it will lead to hydration mismatch.
// Just for educational purposes.
if (typeof window !== "undefined") {
return (
<div>
<h1>🤬</h1>
<p>This is a client component.</p>
</div>
)
}
return (
<div>
<h1>🥰</h1>
<p>This is a server component.</p>
</div>
)
}can you tell what u wanna do
Red carpenter antOP
I need to render this component as server side. But it is being rendered as client because this parent is client component.
You're asking how to do "Y", but what is "X"?
Its a low effort question
If you want further info, I’m basically asking why is the parent client component
Red carpenter antOP
In the parent we are Hooks(states, useEffects to sort and filter)
Asiatic Lion
Change the parent to the server component and make only TemplatesTopbar to client one.
Red carpenter antOP
ok, then i'll have to store all the data on context or something right?
because the top bar handles sorting and filtering.
because the top bar handles sorting and filtering.
Asiatic Lion
wait wait.
seems in TemplateDirectory, there's a button and it has event handler right?
Red carpenter antOP
yeah
Asiatic Lion
I'd like you to check about server/client components again. in your case, TemplateDirectory can't be server component.
Red carpenter antOP
Ok, Thanks
Asiatic Lion
welcome
@Red carpenter ant In the parent we are Hooks(states, useEffects to sort and filter)
Why do you want to use it?
Red carpenter antOP
another question, I am passing this as child (composition pattern)
but it is still not rendering as server side. Shouldn't it render Server Side?
The children is passing from page.tsx file
but it is still not rendering as server side. Shouldn't it render Server Side?
The children is passing from page.tsx file
@Anay-208 Why do you want to use it?
Red carpenter antOP
To sort the templates based on tags and category
@Red carpenter ant To sort the templates based on tags and category
Asiatic Lion
you can set tags and category as a search query params in server component, without useEffect and states.
but the component which has even handlers must be client component, as I said.
Red carpenter antOP
yeah, got it
@Red carpenter ant another question, I am passing this as child (composition pattern)
but it is still not rendering as server side. Shouldn't it render Server Side?
The children is passing from page.tsx file
Asiatic Lion
it should be rendered in client side. cuz parent is client component, and children should not be a component even it's pass from page.tsx, but it should be react element, or elements array.
Red carpenter antOP
@Asiatic Lion can you suggest ways on how to filter & search on server component?
so make only the component which has the feature to change filters and search query to client component.
You don't need to manage them with states, but query params.
after that, in the server component, you could get filters and query value in the prop of page.tsx.
Asiatic Lion
Let me know if it's clear or not
Red carpenter antOP
got it
My question is do I just put the fetched data on a variable and then use it?
And what about updating the existing data(filtering & sorting)? Do I just update that variable
Sorry if these are dumb questions 🙂
And what about updating the existing data(filtering & sorting)? Do I just update that variable
Sorry if these are dumb questions 🙂
Asiatic Lion
oh i just checked your code.
where do you set sort and filter to searchParams?
Red carpenter antOP
yeah
Red carpenter antOP
const handleSort = async (params: any) => {
setIsFiltering(true);
const result: any = await filterTemplates(params);
setIsFiltering(false);
if (result?.templates?.length > 0) {
setTemplates(result.templates);
setTotalTemplates(result.totalTemplates);
}
};
useEffect(() => {
const sort = searchParams?.get("sort");
const filter = searchParams?.get("filter");
const search = searchParams?.get("search") || "";
setSearchQuery(search);
if ((sort || filter) && !search) {
// if filter is empty and sort is newest then set default templates because
// we are already load thr newest templates in server side
if (sort === "latest" && !filter) {
setTemplates(defaultTemplates);
setTotalTemplates(props.totalTemplates);
return;
}
handleSort({ sort, filter });
}
// if sort and filter is empty then set default templates
if (!sort && !filter && !search) {
setTemplates(defaultTemplates);
setTotalTemplates(props.totalTemplates);
return;
} // if search is exist in url query then search get the highest priority
if (search) {
handleSearch(search);
}
}, [searchParams]);Asiatic Lion
I'm saying where, like in which component did you set the searchParams? like
searchParams.set("sort", search)Red carpenter antOP
ok, it's from the TeamplatesTopBar component
Asiatic Lion
okay, then you don't need to get in TemplatesDirectoryCopy. you should get it on parent component(like page.tsx), then just pass it as prop in TemplateDirectoryCopy
then you don't need like useEffect and handleSort in that component (TemplatesDirectoryCopy), then it doesn't need to be client component
Asiatic Lion
not clear? sorry if its dumb explanation 😄
Red carpenter antOP
haha, it's okay.
I've passed it to the other dev. Let's see what he deos
I've passed it to the other dev. Let's see what he deos
Thanks for the explanation though. Apriciate it!
Original message was deleted
Asiatic Lion
^
Please check the other dev's one, and if you think I'm right, mark mine as a solution. 😆
Please check the other dev's one, and if you think I'm right, mark mine as a solution. 😆