When building React applications, you will need to consider what parts of your application should be rendered on the server or the client.
When to use Server and Client Components?
Next 13 introduced server components. A new way to optimize your projects. Server components are the default in the
app router and should be used for everything except when your component needs:
Interactivity and event listeners.
Certain hooks: state and lifecycle hooks, custom hooks that use state of lifecycle hooks, the
useSearchParamshook and other hooks like
Browser only api's.
React class components.
In these cases you use client components.
Client components can be a bit confusing because in
Next they are rarely client-side rendered.
Next optimizes all components (client and server) by prerendering them server-side.
Client components aren't fully server-side rendered. They also render partly client-side.
Server components never render client-side, only server-side.
Here's a quick summary of the different use cases for Server and Client Components:
Composing client and server components:
🌳 Striking the Right Balance
When importing client components it's recommended to move them to the bottom level of a tree where possible, this helps to improve the performance of the application.
We can import a client component normally by using the import statement or via props but server components can be imported into a client component only via props.
Here’s a nice diagram that the Vercel folks created to help you visualize this concept better:
In this example code, instead of making the entire layout a client component, we move the interactive search bar logic to a separate client component. Then, we import this component into the layout using the import statement. By doing this, we can import the client component normally and improve performance by rendering other components such as the logo on the server.
So, we are attempting to import a server component into a client component. Unfortunately, this won't work since we're not permitted to use the import statement when bringing in the server component to the client one.
Instead we can pass the server component as a child or as a prop of a client component, we can achieve this by wrapping both components in another server component. In the example below, the page component is a server component by default and we wrap both the current component and server component within it. Then, we pass the server component as a child to the client component. This allows us to receive the server component using the children prop within the client component and avoid returning it within the client component.
With Next.js 13, you get more flexibility in creating your components. When it comes to rendering, server components can render both server and client components, while client components can only render other client components or server components that are passed in as a prop. This model of composition ensures better interoperability and code reusability.