Passing a server side state to a deeply nested client component
Unanswered
Peterbald posted this in #help-forum
PeterbaldOP
So in Next.js have a cached data fetching function like this:
In server components I can just get the state with
but now I want to use the user object in a client component that is deeply nested.
I've tried to use stores (from zustand), but the problem is that this state is technically available at the initial render, but the store won't update until the component is mounted.
Is there a good way to do this? Tysm
const fetchUser = React.cache(async () => ...);In server components I can just get the state with
const user = await fetchUser();but now I want to use the user object in a client component that is deeply nested.
I've tried to use stores (from zustand), but the problem is that this state is technically available at the initial render, but the store won't update until the component is mounted.
Is there a good way to do this? Tysm
37 Replies
@Peterbald So in Next.js have a cached data fetching function like this:
`const fetchUser = React.cache(async () => ...);`
In server components I can just get the state with
`const user = await fetchUser();`
but now I want to use the user object in a client component that is deeply nested.
I've tried to use stores (from zustand), but the problem is that this state *is technically available* at the initial render, but the store won't update until the component is mounted.
Is there a good way to do this? Tysm
the best way would be to just check where u use your prop the first time and have that wrapped in a ssr component
from there u can pass it down the tree
@gin from there u can pass it down the tree
PeterbaldOP
like... for every child I have a prop that says user
and keep going until i reach that child
@Peterbald like... for every child I have a prop that says user
if ur app is not big u can def do it that way
PeterbaldOP
what is an alternative
why dont u wrap the child which uses user in a seperate wrapper
@gin why dont u wrap the child which uses user in a seperate wrapper
PeterbaldOP
what's an example of that
like i have deeply nested client components
client within client within client within client
so I'll have to pass a server state through all of that
from a server component at the top
@Peterbald client within client within client within client
depends on where u want to use the prop
are u using it in every single client parent client component and passing that down aswell?
PeterbaldOP
no
that's why it's annoying
i only need it in like a deeply nested child
mind sharing me a repo or something
ill show you a example
PeterbaldOP
well the i changed the code base
by a lot
during the last 10 hours
i'm passing the prop down in 4 client components now
cool so u found a way that fits u probably
PeterbaldOP
well it's still ugly
how i have it as a prop only to pass it to a child
@Peterbald So in Next.js have a cached data fetching function like this:
`const fetchUser = React.cache(async () => ...);`
In server components I can just get the state with
`const user = await fetchUser();`
but now I want to use the user object in a client component that is deeply nested.
I've tried to use stores (from zustand), but the problem is that this state *is technically available* at the initial render, but the store won't update until the component is mounted.
Is there a good way to do this? Tysm
uh just put it to a react context and useContext() that react context anywhere you want?
@joulev uh just put it to a react context and useContext() that react context anywhere you want?
PeterbaldOP
but like, a server side value and I have to use it before mount
in client components
async function Page() {
const user = await getUser();
return (
<UserContext user={user}>
...
</UserContext>
)
}"use client";
function ClientComponent() {
const user = useUser();
return ...
}👍
@Peterbald but like, a server side value and I have to use it before mount
what do you mean by before mount? before mount the component doesn't even exist, and something that doesn't exist obviously cannot get a value
here using the context is safe from any rerendering perf problems because the value never changes
PeterbaldOP
oh yeah right
i've been using zustand without contexts too much
if you don't want to use react context then i have a jotai example. i don't use zustand.
"use client";
import { atom, useAtom } from "jotai";
import { useHydrateAtoms } from "jotai/utils";
const userAtom = atom<{ name: string } | null>(null);
function DeeplyNestedComponent() {
const [user] = useAtom(userAtom);
return <div>{user?.name}</div>;
}
export function PageClient({ user }: { user: { name: string } | null }) {
useHydrateAtoms([[userAtom, user]]);
return <DeeplyNestedComponent />;
}don't know how zustand people handle server-side rendering and hydration but in jotai it would be
useHydrateAtoms, probably zustand should have something similar?