ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Next.js] Hydration failed 에러 해결 (Unhandled Runtime Error)
    개발공부/Next.js 2024. 2. 17. 14:37

    본 글은 Next.js로 프로젝트를 진행하면서 발생했던 Hydration failed 에러를 해결한 방법에 대해 다룬 내용입니다.

     

    목차
    1. 에러 발생
    2. 원인
    3. 해결 방법

     

    1. 에러 발생

    소개 페이지에서 로그인 유무에 따라 버튼을 다르게 보이도록 처리하는 과정중에 아래 에러가 발생했다.

    에러 발생

    2. 원인

    에러 원인을 한 줄로 간단하게 정리하자면, 서버와 클라이언트에서 렌더링된 HTML이 일치하지 않아서이다!


    위의 내용을 이해하기 위해서는 Next.js가 서버 사이드 렌더링(SSR)이라는 것을 잊지 말아야 한다.

     

    SSR은 클라이언트와 서버의 렌더링 사이의 일관성을 유지하기 위해 hydrate 과정을 사용한다.

    hydrate
    서버에서 생성된 HTML과 클라이언트 측 JS 코드 간의 일치 여부를 확인 후, 그에 따라 이벤트 핸들러 등을 바인딩 하는 과정


    Next.js는 SSR을 지원하기 때문에  hydrate 과정을 거치면서위에 오류가 발생할 수 있다.

     

    3. 해결 방법

    자, 이제 원인을 알았으니 해결 방법을 찾아봤다.
    (나는 Next.js 공식 문서를 참고했다.)

     

    1. hook을 사용해 데이터가 로드된 후에 렌더링 되도록 처리한다. (useEffect 활용)

    2. 문제가 발생한 특정 구성 요소만 SSR을 비활성화 한다.

     

    나는 두 가지 중 1번으로 에러를 해결했다.

     

    이유는 우리 프로젝트에서 비동기로 데이터를 로딩하면서 생기는 문제였고,

    SSR을 비활성화 하는 방법은 사전 렌더링을 포기하는 것이기 때문에 초기 성능 및 SEO 관점에서 좋지 않았기 때문이다.

     

    그래서 나는 데이터를 useState로 관리 후 useEffect를 활용해 데이터 로딩 완료 후 상태가 업데이트 되도록 했다.

    (github 주소: https://github.com/UniverseStop/FE/blob/dev/src/pages/aboutus/index.tsx)

    const [buttonName, setButtonName] = useState("로그인");
    const userInfo = GetCurrentUser(); // 현재 로그인된 사용자 정보
    const reset = useResetRecoilState(currentUser); // recoil 데이터 초기화
    
    useEffect(() => {
        // 브라우저 닫기 시 리코일 초기화
        const resetRecoil = () => {
            reset();
        };
    
        const token = getSession("access_Token");
        if (!token){
            resetRecoil();
        } else {
            if (userInfo.isLoggedIn) setButtonName("로그아웃");
            else {
                removeSession("access_Token");
                removeSession("refresh_Token");
            }
        }
    
        // beforeunload 이벤트에 대한 리스너 추가 (브라우저가 닫힐 때 실행 예정)
        window.addEventListener("beforeunload", resetRecoil);
    
        return () => {
            // 브라우저 닫기 시에만 초기화 되도록 beforeunload 이벤트에 등록된 리스너를 제거하여 함수 실행
            window.removeEventListener("beforeunload", resetRecoil);
        };
    }, []);

     

    마무리

    이번에는 Next.js에서 Hydration failed 에러 발생했을 때 해결하는 방법에 대해 알아봤습니다.

     

    이번 에러를 통해 Next.js와 SSR에 대해 한번 더 공부할 수 있게 되는 계기가 되었습니다!

    728x90
Designed by Tistory.