🚨 발생 문제
Next.js: Failed to compile
Failed to compile
./src\app\intro\page.tsx
ReactServerComponentsError:
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
🤔 문제 원인
useState를 사용하는 컴포넌트에 Client Component임을 선언해주지 않아서 발생
// src/app/intro/page.tsx
import { useState } from "react";
const Intro = () => {
const [method, setMethod] = useState<"email" | "phone">("email");
const onEmailClick = () => setMethod("email");
const onPhoneClick = () => setMethod("phone");
return (
<div>
<h3>Enter to Carrot</h3>
<div>
{*/ ... 이하 생략 ... /*}
);
};
export default Intro;
🔎 Server Component / Client Component
Next.js 공식 Docs에서 서버 컴포넌트와 클라이언트 컴포넌트의 차이에 대해 아래와 같이 제시해준다.
- Server Component는 토큰, API, Fetch Data 등과 같은 서버 자원과 관련된 컴포넌트이다.
- Client Component는 onClick(), onChange(), 혹은 useState(), useEffect() 등과 같이 유저와의 상호작용이나 state 또는 생명주기 효과와 관련되어 사용자의 영향을 받는 컴포넌트이다.
내가 작성한 page.tsx 페이지 컴포넌트 같은 경우에는 useState를 사용한 클라이언트 컴포넌트인데, 클라이언트 컴포넌트임을 알려주는 코드가 없기 때문에 발생한 에러였다.
💊 해결 방법
1) "use client"로 클라이언트 컴포넌트임을 선언
"use client"; // 이 부분을 선언
import { useState } from "react";
const Intro = () => {
const [method, setMethod] = useState<"email" | "phone">("email");
const onEmailClick = () => setMethod("email");
const onPhoneClick = () => setMethod("phone");
return (
<div>
<h3>Enter to Carrot</h3>
<div>
{*/ ... 이하 생략 ... /*}
);
};
export default Intro;
2) src/app 디렉토리 밖에 컴포넌트를 위치시켜주면 된다.
- ex. app/components
- 하지만 라우팅을 구성하는 page 컴포넌트이므로 src/app/ 외부에 위치시킬 수 없어 "use client";를 선언해주었다.
참고 사이트
[Next.js] Server/Client Component
'✍️ What I Learned > 트러블슈팅' 카테고리의 다른 글
[트러블슈팅] Module not found: Error can't resolve '@/app' (0) | 2024.01.18 |
---|---|
[트러블슈팅] Error: document is not defined (0) | 2023.08.21 |
[트러블슈팅] TS17004: Cannot use JSX unless the '--jsx' flag is provided. (0) | 2023.08.01 |
[트러블슈팅] ERROR in ./node_modules/react-router-dom/dist/index.js 13:0-810 (0) | 2023.06.27 |
[트러블슈팅] Firebase: Error (auth/account-exists-with-different-credential) (0) | 2023.06.26 |