Correct way to fetch data in a server component and pass it to a client component? ReactQuery TRPC

Hi, I want to understand what are the best practices to deal with TRPC and react server components. Say that I want to have a server component that fetches data in the backend using trpc. I understand that if I am in the server I should use createCaller method from trpc. I tried to do it like so, and pass the data I fetch from the caller to my client component:
1 Reply
Gabriel
GabrielOP17mo ago
//Home.tsx-ServerComponent
import type { RouterOutputs } from "@kdx/api";
import { appRouter } from "@kdx/api";
import { auth } from "@kdx/auth";
import { prisma } from "@kdx/db";
//The above are my server side code to handle authentication, importing prisma etc.

import HomePage from "./Home";

export default async function Home() {
const session = await auth();

let initialData: RouterOutputs["workspace"]["getActiveWorkspace"];
if (session.user !== null) {
const caller = appRouter.workspace.createCaller({ session, prisma });
initialData = await caller.getActiveWorkspace();
}

return <HomePage initialData={initialData} />;
// ^^ -- Variable 'initialData' is used before being assigned.ts(2454) (This is erroring for me right now, but I'm sure it can be fixed)
}
//Home.tsx-ServerComponent
import type { RouterOutputs } from "@kdx/api";
import { appRouter } from "@kdx/api";
import { auth } from "@kdx/auth";
import { prisma } from "@kdx/db";
//The above are my server side code to handle authentication, importing prisma etc.

import HomePage from "./Home";

export default async function Home() {
const session = await auth();

let initialData: RouterOutputs["workspace"]["getActiveWorkspace"];
if (session.user !== null) {
const caller = appRouter.workspace.createCaller({ session, prisma });
initialData = await caller.getActiveWorkspace();
}

return <HomePage initialData={initialData} />;
// ^^ -- Variable 'initialData' is used before being assigned.ts(2454) (This is erroring for me right now, but I'm sure it can be fixed)
}
Then, in my HomePage client component:
"use client"
export default function HomePage(props: {
initialData: RouterOutputs["workspace"]["getActiveWorkspace"];
}) {
const sessionData = useSession();
const { data: workspace } = api.workspace.getActiveWorkspace.useQuery(
undefined,
{
refetchOnWindowFocus: false,
enabled: sessionData.data?.user !== undefined,
initialData: props.initialData,
},
);

return (
<main>
{sessionData.data && (
<p>Your current active workspace is:</p>
<div className="text-bold text-primary inline-flex h-[40px] items-center">
<Avatar className="my-auto mr-2 h-5 w-5">
<AvatarImage
src={`https://avatar.vercel.sh/${sessionData.data.user.id}kdx.png`}
alt={workspace?.name}
/>
<AvatarFallback>
{workspace?.name
.split(" ")
.map((n) => n[0])
.join("")}
</AvatarFallback>
</Avatar>
<span className="">{workspace?.name}</span>
</div>
)}
</main>
);
}
"use client"
export default function HomePage(props: {
initialData: RouterOutputs["workspace"]["getActiveWorkspace"];
}) {
const sessionData = useSession();
const { data: workspace } = api.workspace.getActiveWorkspace.useQuery(
undefined,
{
refetchOnWindowFocus: false,
enabled: sessionData.data?.user !== undefined,
initialData: props.initialData,
},
);

return (
<main>
{sessionData.data && (
<p>Your current active workspace is:</p>
<div className="text-bold text-primary inline-flex h-[40px] items-center">
<Avatar className="my-auto mr-2 h-5 w-5">
<AvatarImage
src={`https://avatar.vercel.sh/${sessionData.data.user.id}kdx.png`}
alt={workspace?.name}
/>
<AvatarFallback>
{workspace?.name
.split(" ")
.map((n) => n[0])
.join("")}
</AvatarFallback>
</Avatar>
<span className="">{workspace?.name}</span>
</div>
)}
</main>
);
}
I want to understand, what are the best practices to using server components with TRPc. How should I correctly fetch the data first on the server and then pass it down to react query? Is there a better/More elegant way?
Want results from more Discord servers?
Add your server