By default, any component in the /app directory comes as a react server-side component. And this brings some serious performance advantages.
However, there are things that we can't do on the server side. Things like using the window object or managing the client-side state. For situations like these, we have the client components.
You can declare a NextJs component as a client component by using the "use client"
directive:
"use client"
export default function MyClientComponent() {
// code here
}
For example, if you try to use the useState() hook without declaring the component as client-side we will get an error:
import { useState } from "react"
export default function MyClientComponent() {
const [myVal, setMyVal] = useState(0)
return (<h1>{myVal}</h1>)
}
You will get the below error:
You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.
,----
1 | import { useState } from "react"
: ^^^^^^^^
`----
Maybe one of these should be marked as a client entry with "use client":
Or, if we try:
import { useEffect } from "react"
export default function WithEffectPage() {
useEffect(() => {})
return (<h1>da</h1>)
}
We will get:
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.
Both of these errors will be fixed by adding the "use client"
directive:
"use client"
import { useState } from "react"
export default function MyClientComponent() {
const [myVal, setMyVal] = useState(0)
return (<h1>{myVal}</h1>)
}
Some notes on the client components in NextJs:
- the
"use client"
directive needs to be added as the first line in the file, before any imports - we cannot directly use a server component directly into a client component.
- performance wise we should keep the client components at a minimum. For example, according to the documentation, if we have a search box that uses a state we should extract that search box in a client-side component instead of declaring the whole page as a client component:
// SearchBar is a Client Component import SearchBar from './SearchBar'; // Logo is a Server Component import Logo from './Logo'; // Layout is a Server Component by default export default function Layout({ children }) { // code here }
When to use the "use client" directive in NextJs 13
You should declare a component as a client-side component in one of the following situations:
- when we use event listeners (eq:
onClick
,onChange
) in our components - when we use hooks like
useState()
,useReducer()
,useEffect()
, or other custom hooks that are depending on the state or lifecycle hooks - when we use browser-only APIs (eq:
window
,document
) or hooks that use these APIs - when you want to use localStorage in your components
- some very particular cases for data fetching
Importing a Server Component in a Client Component
We cannot directly import a Server Component into a NextJs 13 Client Component. The reason for this is that the server component can contain code for things like reading/writing files or databases on the server side. We can overcome this obstacle by using only the rendered server component in the client one.
📖 50 Javascript, React and NextJs Projects
Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects with project briefs and wireframes! Choose from 8 project categories and get started right away.
📖 50 Javascript, React and NextJs Projects
Learn by doing with this FREE ebook! Not sure what to build? Dive in with 50 projects with project briefs and wireframes! Choose from 8 project categories and get started right away.