Feel free to correct me at any point here. I am a firmware developer turned hobby web developer. For context I am using React/NextJS.
I am making a website for a small event. Using SSR I wanted to pull a bit of event data from the database (like date, event name, etc) and provide this to components. Originally I thought to use React’s context mechanism to prevent prop drilling, but I found this does not seem to work well with SSR and appears to mostly (?) be a CSR feature (some dead references to createServerContext
were found).
Unless I am interpreting this incorrectly, NextJS’s comment on context in SSR is basically ‘use CSR’. Their suggestion was to just wrap the context providers with ‘use client’, which effectively means the entire site is now CSR, right?
So from here I thought I might just pass the event information directly to the children. One level deep, two components (the site is simple). But in order to do that with NextJS’s layouts it seemed like I had to make use of a combination of React.Children.map
and React.cloneElement
. I found a number of sources online claiming this to work:
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const info = (await getEventInfo())
return (
<html lang="en">
<body className={font.className}>
{Children.map(children, (child) => {
return cloneElement(child as any, { info }) //TS issue with child here?
})}
</body>
</html>
);
}
None of the references were specifically using the pattern from within a NextJS layout. Although from what I know it seems like it ought to work just the same.
In these child pages I printed the value of the generic props object and it’s just { params: {}, searchParams: {} }
. It does work to render the child element. It does not work to add extra props.
Am I doing something wrong here? Is this meant to work? Can it be done some other way? Open to critiques and other options.
PS: the TypeScript compiler was complaining about the type of child
as given to cloneElement
. Perhaps this is (one of) the issue(s)? Although it does render the child properly (without the prop addition) so maybe not.