문제 정의
// apps/layout.tsx
export default function layout({children}){
// ..
return (
<SessionProvider>{children}</SessionProvider>
)
}
layout.tsx에서 SessionProvider로 전체를 감싸면 위와 같은 에러가 발생한다.
사실 수집
1. SessionProvider는 뭐하는 컴포넌트일까?
-
코드
// next-auth/src/react.tsx export function SessionProvider(props: SessionProviderProps) { if (!SessionContext) { throw new Error("React Context is unavailable in Server Components") } // .. const value = { data : session, status : loading, async update(){ //.. }, } // .. return ( <SessionContext.Provider value={value}>{children}</SessionContext.Provider> ) }SessionProvider는 next-auth에서 제공해주는 컴포넌트로, 이름에서도 알 수 있듯이 Session과 관련된 값과 함수(data, status, update)를 뿌려주는 Context Provider이다.
원인 추론
Context Provider는 Client Component이다. Client Component인데 서버 컴포넌트인 layout.tsx에서 호출해서 발생한 에러이지 않을까 생각했다. 하지만, React에서도 사용 가능하다고 한 방식인 RCC안에 RSC를 감싼 건데? children으로 감싸는 것은 허용하기 때문이다.
해결 방안 수립
이전에 React Server Component를 공부하면서 읽었던 내용이 떠올랐다.
[Third-party packages](https://app.notion.com/p/1898338855eb406ebc1df364dc71685e#5e9ffa0a1b534d348680454fd237ed55)
Third-party packages
-
npm packages에 있는 client 전용 기능을 사용하는 많은 컴포넌트들은 아직까지
use client지시문이 없음. 이것들을 Server component로 동작하는 곳에다가 import해서 사용한다면 제대로 작동하지 않고 오류를 일으킴. 이를 해결할 수 있는 방법은client component를 따로 만들어서 import한 다음 그걸 다시 export 시켜주는 것'use client'; import { AcmeCarousel } from 'acme-carousel'; export default AcmeCarousel;
바로 아직 Client Component를 지원하지 않는 서드 파티 패키지를 사용하는 방법이다. ‘use client’를 선언한 파일을 만들어, import 후 export하는 것이다. 그럼, 이 파일은 기존에는 ‘use client’가 명시되지 않은 server component였지만, ‘use client’를 명시한 파일에서 export함으로써 client component가 된다.
조치 및 구현
// src/components/ClientSessionProvider.tsx
'use client';
import { SessionProvider } from 'next-auth/react';
export default SessionProvider;
// src/apps/layout.tsx
export default function layout({children}){
// ..
return (
<ClientSessionProvider>{children}</ClientSessionProvider>
)
}
해결이 되었다 🎉
결과 관찰
그렇다면, 이 문제가 왜 발생한걸까?
SessionProvider가 선언된 next-auth/src/react.tsx에는 파일의 가장 상단에 "use client"가 명시되어 있다.
근데, 내가 설치한 next-auth의 해당 파일에는 ‘use client’가 없다.
아직 반영이 되기 전인가? 싶었다. 그래서 확인을 해보니
그렇다. v5에서 반영될 사항이고, 아직 5.0은 베타 버전이고 안정적인 버전은 4.xx이다.
결론
파일 상단에 ‘use client’를 추가하여 Next.js 13 App Routing의 RSC에서 사용을 해도 에러가 발생하지 않게 수정이 되었다. 하지만 아직 V4까지 안정적인 버전이고, 해당 사항은 V5에서 반영될 사항이라 적용이 안된 것이었다.
그렇다면 지금 상황에서는 다른 파일에서 ‘use client’를 추가하여 import & export하는 방식이 최선이라 생각한다.