Server Error
Error: createContext only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/context-in-server-component
원인 : 클라이언트 컴포넌트에서만 사용가능한 createContext를 사용해서 생긴 에러. 컴포넌트가 있는 파일 최상단에 'use client'를 쓰면 해결되다고 한다.
그러나, metadata를 export 하고 있었기 때문에 관련 파일들을 client 모듈로 선언할 수 없었다. 'use client'를 선언할 경우 선언 아래로 실행되는 컴포넌트들은 모두 client 모듈로 실행된다. 사용하고 있는 Next.js v14에는 metadata API가 있어서 Layout파일에서 metadata를 export할 경우 이를 받아 실행하는 어플리케이션의 metadata를 정의하고 자동으로 head값을 설정한다.
Error: × You are attempting to export "metadata" from a component marked with "use client", which is disallowed. Either remove the export, or the "use client" directive. Read more: https://nextjs.org/
RootLayout에서 metadata를 설정하고 Recoil을 설정하거나 Suspense컴포넌트를 사용하기 위해서 Provider라는 클라이언트 컴포넌트를 별도로 생성하고 생성한 Provider컴포넌트로 RootLayout의 children을 감싸줬다.
에러 덕분에 Provider안에 필요한 설정 컴포넌트드을 모아 놓을 수 있어서 코드가 깔끔해졌다.
// 기존 코드 컴포넌트
return (
<QueryClientProvider client={queryClient}>
<RecoilRoot>
<Gnb />
<Suspense fallback={'loading...'}>
{children}
</Suspense>
</RecoilRoot>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
);
바뀐 후 컴포넌트.
// Provider.tsx
function Provider(){
return (
<QueryClientProvider client={queryClient}>
<RecoilRoot>
<Suspense fallback={'loading...'}>{children}</Suspense>
</RecoilRoot>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
);
}
// RootLayout.tsx
function RootLayout() {
return (
<html lang="en">
<body className={inter.className}>
<Provider>
{children}
</Provider>
</body>
</html>
);
}
Next12를 써보고 13을 건너뛰고 14를 써봐서 그런지 많이 바뀌었다.
참고
'TIL' 카테고리의 다른 글
2024년 2월 회고 (0) | 2024.02.29 |
---|---|
[TIL] 이벤트 버블링? (0) | 2024.01.23 |
자바스크립트의 비동기 처리 (0) | 2024.01.12 |
Git rebase (0) | 2023.10.07 |