NextJS 14 버전 기준으로 블로그를 만드는 과정을 작성해두려 한다.
오늘은 Provider 역할을 하는 부분을 코딩을 진행하였다.
use client"; // Client Side 동작
import { createContext, useEffect, useRef } from "react";
import { ThemeProvider, useTheme } from "next-themes";
import { usePathname } from "next/navigation";
// 제네릭 타입으로 인한 함수 선언식 변경
function usePrevious<T>(value: T) {
let ref = useRef<T>(value);
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}
const ThemeWatcher = () => {
let { resolvedTheme, setTheme } = useTheme();
useEffect(() => {
let media = window.matchMedia("(prefers-color-scheme: dark)");
const onMediaChange = () => {
let systemTheme = media.matches ? "dark" : "light";
if (resolvedTheme === systemTheme) {
setTheme("system");
}
};
onMediaChange();
media.addEventListener("change", onMediaChange);
return () => {
media.removeEventListener("change", onMediaChange);
};
}, [resolvedTheme, setTheme]);
return null;
};
export const AppContext = createContext<{ previousPathname?: string }>({});
export const Providers = ({ children }: { children: React.ReactNode }) => {
let pathname = usePathname();
let previousPathname = usePrevious(pathname);
return (
<AppContext.Provider value={{ previousPathname }}>
<ThemeProvider attribute="class" disableTransitionOnChange>
<ThemeWatcher />
{children}
</ThemeProvider>
</AppContext.Provider>
);
};
블로그에는 공통으로 적용되는 테마가 있다고 생각되어졌다.
헤더라던가 레이아웃 부분이 페이지마다 공통적으로 적용된 부분이 존재했다.
(Navigation, LayOut 등)
블로그에 테마와 관련된 Provider를 구성하여, 테마와 경로 관련 상태를 관리하는 역할을 만들어주었다.
Provider에 컨텍스트와 훅을 심어주어서 상태를 관리하게 공통적 모듈 역할을 해준다면 깔끔하게 테마가 공통적으로 적용될거 같았다.