다음과 같이 다크 모드 적용을 위해 localstorage
에 theme 저장 후 이 값을 가져와서 새로고침이 되더라도 theme를 유지하려 했다.
import { extendTheme, type ThemeConfig } from "@chakra-ui/react";
const initialColorMode = localStorage.getItem("chakra-ui-color-mode");
const config: ThemeConfig = {
initialColorMode: initialColorMode,
useSystemColorMode: true,
};
const theme = extendTheme({ config });
export default theme;
그런데 위와 같이 localStorage
를 찾지 못하고 있어서 문제 해결에 어려움이 있었다. 왜 localStorage를 찾지 못했을까??
NextJS에서는 서버 사이드 렌더링 과정 중
window객체
에 접근할 수 없다. 그렇기 때문에 window객체인 localStorage 또한 접근할 수 없었던 것이다.서버 사이드 렌더링 후 클라이언트 사이드에서 접근을 해야 했다.
typeof window !== 'undefined'
페이지가 client에 마운트될 때까지 기다렸다가 localStorage에 접근해야했다 그러므로 window객체가 있을때 loacal저장소에 접근했다.
if (typeof window !== 'undefined') {
localStorage.getItem('accesstoken');
}
===>> 적용방법
const initialColorMode =
typeof window !== "undefined"
? localStorage.getItem("chakra-ui-color-mode")
: null;
하지만 문제는 계속 되었다.
"use client";
import { CacheProvider } from "@chakra-ui/next-js";
import { ColorModeScript, ThemeConfig, extendTheme } from "@chakra-ui/react";
import dynamic from "next/dynamic";
import { useEffect, useState } from "react";
const ChakraProvider = dynamic(() =>
import("@chakra-ui/provider").then((mod) => mod.ChakraProvider)
);
export function Providers({ children }: { children: React.ReactNode }) {
const [initColor, setInitColor] = useState<string | null>("");
useEffect(() => {
const themeColor = localStorage.getItem("chakra-ui-color-mode");
setInitColor(themeColor);
}, []);
const config: ThemeConfig = {
initialColorMode: initColor,
useSystemColorMode: true,
};
const theme = extendTheme({ config });
return (
<ChakraProvider theme={theme}>
<ColorModeScript initialColorMode={theme.config.initialColorMode} />
<CacheProvider>{children}</CacheProvider>
</ChakraProvider>
);
}
useEffect를 사용해서 mount되었을 때 theme를 적용하였다. 참고로 react hook은 클라이언트 컴포넌트에서만
사용가능 하다는 것을 잊지말자.
영상과 같이 적용이 잘되는 것을 확인할 수 있었다.