Passing server side props into deeply nested components
Answered
African Slender-snouted Crocodil… posted this in #help-forum
African Slender-snouted CrocodileOP
getServerSideProps
can [only be exported from a page](https://nextjs.org/docs/pages/building-your-application/data-fetching/get-server-side-props#behavior). This makes sense. However, I am wondering if there is an idiomatic way to pass these props into deeply nested components without using prop-drilling. useContext
isn't appropriate since it's a react hook that can only be run on the client.Something like:
// pages/profile.tsx
export const getServerSideProps = async () => {
// fetch user data from database
const res = await fetch("...");
const data = await res.json();
return {
props: {
isSubscribed: data.isSubscribed
}
}
}
export const ProfilePage = (props) -=> {
return (
<PageLayout isSubscribed={props.isSubscribed}>
{ ... }
</PageLayout>
)
}
Then what if I want to pass
isSubscribed
to a <Nav />
component and then pass that to the <LoginButton />
component, which then passes it down to something else...How do I avoid prop drilling in this case?
Answered by African Slender-snouted Crocodile
For future me or anyone
Then the page
Then in deeply nested components...
getServerSideProps
:export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
const subscriptionStatus = await getSubscriptionStatus(ctx)
return {
props: {
isSubscribed: subscriptionStatus.isSubscribed,
},
}
}
Then the page
export default function Home(
props: InferGetServerSidePropsType<typeof getServerSideProps>
) {
const { isSubscribed } = props
return (
<SubscriptionProvider isSubscribed={isSubscribed}>
<Layout></Layout>
</SubscriptionContext>
)
}
Then in deeply nested components...
const {isSubscripted} = useSubscription()
4 Replies
joulev
you are using the pages router (
getServerSideProps
only works in the pages router). then just use useContext or any client-side state management libraries of your choice. all components in the pages router are client components.African Slender-snouted CrocodileOP
yeah I ended up going with a
<SubscriptionContext />
and just wrapping each (necessary) page with that. then initializing the context at the top level page component using the data from getServerSideProps
African Slender-snouted CrocodileOP
For future me or anyone
Then the page
Then in deeply nested components...
getServerSideProps
:export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
const subscriptionStatus = await getSubscriptionStatus(ctx)
return {
props: {
isSubscribed: subscriptionStatus.isSubscribed,
},
}
}
Then the page
export default function Home(
props: InferGetServerSidePropsType<typeof getServerSideProps>
) {
const { isSubscribed } = props
return (
<SubscriptionProvider isSubscribed={isSubscribed}>
<Layout></Layout>
</SubscriptionContext>
)
}
Then in deeply nested components...
const {isSubscripted} = useSubscription()
Answer
African Slender-snouted CrocodileOP
Thx