[Error] Unhandled Runtime Error

Hannahhh·2023년 1월 20일

Error

목록 보기
1/1

Unhandled Runtime Error

Error: Hydration failed because the initial UI does not match what was rendered on the server.

See more info here: https://nextjs.org/docs/messages/react-hydration-error


공식문서를 보고, 서버에서 미리 렌더링된 UI와 브라우저의 UI의 차이가 있어 발생한 오류로 이해했다.
해당 에러가 모든 페이지에서 새로고침해도 계속 나와서 SideBar의 문제임을 알았다..


기존과 다른 점은 로그인을 구현하면서 로그아웃 상태일 때, 로그아웃 버튼이 보이지 않고 접근가능한 메뉴 리스트가 달라지도록 코드를 추가했다는 점이다.

  <NavList>
        {(isLogin ? LoginMenus : LogoutMenus).map(menu => (
          <List
            key={menu.id}
            className={`${router.pathname === menu.href && "text-yellow-200"}`}
          >
            <Link href={menu.href}>
              <span className="text-2xl block float-left">{menu.icon}</span>
              <span className="text-base font-medium p-5">{menu.title}</span>
            </Link>
          </List>
        ))}
        {isLogin && (
          <List>
            <div
              role="presentation"
              onClick={() => setShowModal(true)}
              className="cursor-pointer"
            >
              <span className="text-2xl block float-left">
                <AiOutlineLogout size="35px" />
              </span>
              <span className="text-base font-medium p-5">로그아웃</span>
            </div>
          </List>
        )}
      </NavList>
  • 너무 당연한 걸.. 잊고 있었다..
    ssr시점에서는 localStorage 값을 알 수 없는데 자꾸 localStorage에 저장해둔 값으로 로그인 여부를 확인하려고 하니까 계속 고쳐지지 않았던 것이었다.
    (* 위의 코드의 isLogin은 recoil-persist을 사용해 로컬스토리지에 두고 관리하는 값을 recoilValue로 불러온 값!)

login여부는 useState로 관리하고 useEffect안에서 토큰 유무를 판단해 관리하는 방법으로 해결했다.

const [isLogin, setIsLogin] = useState(false);

  useEffect(() => {
    if (typeof window !== "undefined") {
      if (localStorage.getItem("authorization")) {
        setIsLogin(true);
      } else {
        setIsLogin(false);
      }
    }
  }, []);

0개의 댓글