Tuesday, May 14, 2024
 Popular · Latest · Hot · Upcoming
189
rated 0 times [  195] [ 6]  / answers: 1 / hits: 15118  / 1 Year ago, fri, december 30, 2022, 12:00:00

The simple below component is throwing the following error in Next.js's app directory when I use useState:



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.



import { useState } from "react";

export default function Card() {
const [state, setState] = useState("");

return <></>;
}

More From » reactjs

 Answers
6

In the app directory, by default, Next.js uses Server Components, where the JSX gets compiled to "pure HTML" and sent to the browser. Like any traditional Backend with a templating engine, such as Express with EJS, and Laravel with Blade. This is for better performance, as you can read on the doc:



Server Components allow developers to better leverage server infrastructure. For example, large dependencies that previously would impact the JavaScript bundle size on the client can instead remain entirely on the server, leading to improved performance. They make writing a React application feel similar to PHP or Ruby on Rails, but with the power and flexibility of React for templating UI.



And a Server Component shouldn't contain front-end-specific code, for example, hooks such as useState or useEffect. If you need that, your component or one of its parents should have "use client" at the top, to make it a Client Component:


"use client"; // this is a client component 👈🏽

import { useState } from "react";

export default function Card() {
const [state, setState] = useState("");

return <></>;
}

Now, say you are importing a client-specific library that's not yet marked "use-client" by the maintainers. It will work in your Client Components as-is. But to import it into a Server one, you could, for example, create a lib folder at the same level as app in which you add:


// lib/mui.js

"use client";

export * from "@mui/material";

And import it from there:


import { Button } from "../lib/mui";

export default function Page() {
return (
<div>
<Button variant="contained">Hello World</Button>
</div>
);
}

Finally, if you are getting a similar error while setting up a context, it means you trying to set it up in a Server Component. The guideline is to add it in its own "use client" marked file:


// app/theme-provider.tsx

'use client';

import { createContext } from 'react';

export const ThemeContext = createContext({});

export default function ThemeProvider({ children }) {
return <ThemeContext.Provider value="dark">{children}</ThemeContext.Provider>;
}

And import it from there in your Sever Component:


// app/layout.js

import ThemeProvider from './theme-provider';

export default function RootLayout({ children }) {
return (
<html>
<body>
<ThemeProvider>{children}</ThemeProvider>
</body>
</html>
);
}

[#2] Wednesday, September 14, 2022, 2 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
muhammadbrandend

Total Points: 670
Total Questions: 95
Total Answers: 97

Location: Saint Vincent and the Grenadines
Member since Sat, Sep 11, 2021
3 Years ago
;