Client Components and use client in Next.js App Router
Are you considering using the latest Next.js App Router? Finding yourself adding the use client
directive in lots of files? Or hitting this error:
1Error: 2 3You'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. 4 5 ,---- 6 1 | import { useEffect } from 'react'; 7 : ^^^^^^ 8 `----
By default, every component in the Next.js App Router will be a Server Component. Server Components are excellent. There are many reasons for them to be the default, but now you must explicitly tell Next.js when you have a component that needs client interactivity. Not everything can be done sever-side. That’s where Client Components come in.
Declaring a Client Component
To fix the above error, you must make your component a Client Component. To declare a Client Component, you add the use client
directive to the top of the file.
1'use client' 2import { useState } from 'react'; 3 4export default function Counter() { 5 const [active, setActive] = useState(false); 6 7 return ( 8 <> 9 // Your code here 10 </> 11 ); 12}
The component above requires use client
because it has useState
in it. State cannot be handled server-side. Other common reasons to have use client
would be if your component uses useEffect
, useRef
, or onClick
.
Depending on your application requirements, you may add use client
to several of your components. Adding use client
is okay, but it is good to understand what adding use client
does to your components.
What does use client
do in Next.js?
Adding the use client
directive turns a component into a Client Component. A component must be a Client Component if it requires client-side interactivity (useState, OnClick, etc).
💡 The Next.js documentation states: You can think of Client Components as how Next.js 12 and previous versions worked (i.e. the pages/
directory). Rendering Docs
How is a Client Component rendered?
A Client Component is pre-rendered on the server and hydrated on the client. Now, this is where I needed clarification, so I did the research and wrote this article.
What does it mean to be pre-rendered on the server and hydrated on the client? Are client components only rendered partially client-side?
Pre-rendering vs. Hydration in Next.js
Pre-rendering is when HTML is generated in advance (server-side or during build time) with minimal JavaScript.
Hydration occurs once the page gets loaded into the browser. JavaScript gets executed, and your component becomes interactive.
So a Client Component isn’t entirely client-side. Next.js tries to do as much work as possible in the pre-rendering step to alleviate the work required client-side. Pre-rendering the HTML in advance without interactivity. Then, hydrate that HTML structure with the event handlers and interactivity.
There are two forms of pre-rendering in Next.js: Static and Server-Side. Static or Server-Rendered is determined by how you fetch your data in Next.js.
1 const staticPreRendering = await fetch(`https://...`, { cache: 'force-cache' }); 2 3 const serverPreRendering = await fetch(`https://...`, { cache: 'no-store' });
Before the Next.js 13 App Router, the pre-rendering method was determined by getStaticProps
or getServerSideProps
.
You can learn more about how data fetching has changed in Next.js 13 in a previous post of mine 3 Big Changes in The New Next.js App Folder Architecture.
Does having use client
mean I’m using Next.js 13 wrong?
No.
Before the new App Router, every component was a Client Component. Now that Server Components have been introduced, the distinction between Client Components and Server Components is essential, but having Client Components does not mean you are using the App Router wrong.
Try to use Server Components as much as possible in your application. One benefit is that they help reduce the amount of JavaScript required on the client, thus speeding up performance. The best way to ensure you use Sever Components is to build small single-purpose components. Single-purpose components will help you separate components needing client-side interactivity and those not.
💡 For more on why you should use Server Components whenever possible, check out: What and Why: React Server Components in Next.js 13.
Closing
Building with the new Next.js App Router means you must learn to use the use client
directive. Having use client
in your application is inevitable. I cannot imagine having a real-world application built with Next.js that does not need useState
or useEffect
in a component.
If you put use client
in every component, you may need to reconsider your architecture and separate your components more.
Want more content about the new App Router architecture? Check out 3 Big Changes in The New Next.js App Router Architecture.