How to fix: 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.
If you’re familiar with Next.js 13 and are migrating or upgrading to use Next.js 14, you might see an error like the following as you construct your components and use React hooks like useState
, useEffect
, useContext
, or useQuery
.
The error might look like this:
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. │ Learn more: https://nextjs.org/docs/getting-started/react-essentials
This error message is really not very helpful, and leaves a lot to be desired about what the actual solution would be.
So how do we fix this?
Component Architecture
To build our example, let’s say that we have a component.tsx
that includes logic for a stepper (i.e. to count), so we will use useState
in the component… and we want to use that in our main page.tsx
file.
[component.tsx] —> [page.tsx]
The Issue
We should just be able to import the component into our page, but because of Next.js 14’s implementation of server components (by default), every .tsx
or .jsx
file you write will be a server component, and not a client component.
You might be thinking, well I thought they are just components. There is a difference? 🤔💭
It turns out that there is a difference, and anytime you’ve used a React hook like useEffect
, or useState
, or useQuery
, or useContext
, you have been indirectly (or directly) writing client React components. This is because the state and data types that are rendered around these components only exist after the DOM has loaded.
We need to specify the distinction of client-only components.
The Solution
To fix this issue, you will need to add the following line of code to line 1 of your file that has the React component:
"use client";
This will denote to the DOM that this component doesn’t rely on server-side rendering, so render it as a client React component.