We know that we need to use a Client Component
if we want any interactive functionality.
But in our application we don't have
a single component of course,
we have many components, some of
them nested inside one another.
So in this video I want to show you
how the "use client" directive
affects nested components.
At the moment the ShareLinkButton
is used inside the ReviewPage.
And in fact we can see that the server
renders both the ReviewPage
and the ShareLinkButton.
While client-side rendering is only
done for the Client Component.
Now, instead of displaying only
the "Share link" button,
in our page we may want to show
other buttons as well,
to let users share the review on Twitter,
Facebook, and so on.
So we could create another component
to group all those buttons.
Let's add a new file, called "ShareButtons.jsx".
Now, this is just a demo for this video.
Be aware that I'll discard all these
changes after this video.
But in this ShareButtons component
we could return a "div" grouping a few buttons.
Let's include our existing ShareLinkButton,
and then add another button for Twitter,
and a third one for Facebook for example.
I just put some placeholders,
because we're not actually going to
implement those other buttons.
But this way we could use this ShareButtons
component in the ReviewPage,
in place of the "ShareLinkButton".
Which also means we no longer need
to import that other component.
Ok, if we save,
we now have three different
ways to share the review.
Two of them are just placeholders,
but you get the idea.
Now, let's add a log statement here,
printing when this component is rendered,
as usual.
This way, if we keep an eye on the logs,
and reload the page,
we can see that ShareButtons
only renders on the server,
because it's currently a Server Component.
We know that all components are
Server Components by default.
But if we change it to be a Client Component,
by adding the "use client" directive at the top,
then any other components used inside this one
will also automatically be Client Components.
This means that, in "ShareLinkButton.jsx"
we no longer need "use client".
Let's repeat our usual experiment
of clearing the logs and reloading the page.
You can see that ShareButtons
rendered in the browser,
because it's now a Client Component,
but ShareLinkButton is also treated
as a Client Component,
even though we removed the "use client" directive.
So, when you opt in to client-side
rendering for a component,
it will apply to all its child components as well.
It has to be this way, because
when this component renders in the browser
it will also need to render all its children,
so they will also need to use
client-side rendering.
Now, this also raises an interesting question:
at what level should we put
the "use client" directive?
In theory, we could even set it
in the ReviewPage component,
and use client-side rendering for the whole page.
In practice, this won't work in this case.
The error says we cannot export
a "generateMetadata" function
from a component marked with "use client".
That's because "generateMetadata"
only works on the server.
Even if we try commenting this out,
we then get another error,
because some of our code is trying to use
the Node.js "fs" module.
In this page we call the getReview function,
that uses "readFile" to load the Markdown data.
And that function is only available
when running in Node.js.
It will not be available in the browser,
so we cannot use it in a Client Component.
If a component uses any server-side functionality,
like in this case,
then it must be a Server Component.
In any case, it's not usually a good idea
to use client-side rendering for an entire page,
because that will send an awful lot
of JavaScript code to the browser.
We want to use Client Components
only when it's necessary.
In this example, ShareButtons
can be a Server Component.
It's only in ShareLinkButton that
we use client-side functionality.
So we should only mark this one with "use client".
Each page is rendered from a component tree,
where at the top you have the RootLayout,
that always contains the NavBar,
and then the page-specific component,
in this case ReviewPage.
This will in turn have other nested components,
like the Heading, and ShareButtons,
and the latter includes the ShareLinkButton.
In general, we want to minimize the amount
of code we send to the browser.
That's why we should try to put "use client"
only at the leaves of our component tree.