I have a server component InitView;
const InitView = () => {
useEffect(() => { });
return (
<>
<Hero/>
<span className="text-xl font-normal text-gray-100">Now, how do you want to play?</span>
<GameModeMenu/>
</>
);
}
export default InitView;
Also I have one more server component View;
interface ViewProps {
children?: React.ReactNode;
}
const View = ({children}:ViewProps) => {
return (
<main className="home w-screen h-screen flex flex-col gap-10 justify-start items-center bg-neutral-900 px-8 py-10">
{children}
</main>
);
}
export default View;
And here is my page.tsx
export default function Page() {
return (
<View>
<InitView/>
</View>
)
}
When I tried to import the InitView inside the View component with pass-child method it throws an error;
You're importing a component that needs useEffect. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.
I'm completely okay with this error since I'm trying to use an effect inside a server component. However here is the thing , if I change my codes to this;
Page.tsx
export default function Page() {
return (
<View/>
)
}
View.tsx
"use client";
const View = () => {
return (
<main className="home w-screen h-screen flex flex-col gap-10 justify-start items-center bg-neutral-900 px-8 py-10">
<InitView/>
</main>
);
}
export default View;
The error is gone now. To clarify;
I can use an effect inside my InitView component without any "use client" markings since I directly imported it in View(marked as client) component.
I'm assuming every directly imported (server or client) components inside client components, will be client components, as the previous error says none of its parents are marked with "use client", so they're Server Components by default.
Have you guys any ideas? Am I wrong or correct?
P.S. The documentation says I can not import server components inside client components but as clearly can be seen, I can. I'm highly confused.
This question already has enough explanations, but I will try to clarify some things a bit.
TL:DR: you need that 'use client' directive to use client-only features. Once the component became client-side, its nested components are client-side too. No way to change or intercept this behavior.
Some important details to clarify:
useEffect, useRouter and so).page.jsx=>PageMain.jsx=>SomeModal.jsx all 3 are server-sided by default.PageMain.jsx
component (useEffect, useState, useRouter, page transitions, client-side libs...), you need to mark the component as client: 'use client'. Now PageMain.jsx will render on the client side. And its children will render on client side, too. And its grandchildren will. You got it)))'server-only' and 'client-only'. These doesn't allow you make a component server-only again. These are just for the errors generation. see the docs hereSuspense or dynamic examples from docs). But don't trick yourself. This works more like get-request with 'component' response type. That component will be inserted inside your client-side tree. This is close to the situation "fetch some raw html, then insert it inside your components tree with with dangerouslySetInnerHTML". For sure, in this case your server data is rendered on the server first, and thus can use DB queries. It can use some other server components, but again, no client functionality on the server.I have many projects, and none of them can be made at least 50% server-only. I personally wouldn't hope that "server-only" components can magically solve any optimization problems or speedup any normal site like Medium.com or Reddit significantly.
I hope that my deep explanations and various examples will help somebody.
As per my understanding, we can't import Server Components inside Client Components only when the Server Components contain any server only code (for instance, a database calling or using component level async/await ).
In your case InitView don't have any server-specific code, so importing it inside a Client Component, may infer it to Client Component.
You can find it on Next.js' beta docs - Link
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With