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>
login여부는 useState로 관리하고 useEffect안에서 토큰 유무를 판단해 관리하는 방법으로 해결했다.
const [isLogin, setIsLogin] = useState(false);
useEffect(() => {
if (typeof window !== "undefined") {
if (localStorage.getItem("authorization")) {
setIsLogin(true);
} else {
setIsLogin(false);
}
}
}, []);