Next.js 다크 모드 구현 (feat. Styled components)

NextJs + Styled component 환경의 블로그를 제작한 뒤 다크 모드가 있으면 좋을 것 같다는 생각이 들어 기능을 구현하기로 하였다.
 
우선 테마를 변경하는 기능을 담당하는 useTheme custom hook 을 생성해주었다.
 
그리고 각각의 테마에 대한 스타일을 생성해준다.
 
타입스크립트를 통해 개발을 진행한다면 위의 코드는 타입스크립트 에러가 발생하기 때문에 d.ts 파일을 통해 DefaultTheme 의 타입을 명시해준다.
 
styled-components 의 ThemeProvider 는 하위 항목에 theme 라는 상태 값을 Context API 을 통해 전달해주는 역할을 한다. 그렇기 때문에 최상위 컴포넌트인 _app.tsx 에 하위 항목들을 감싸준 뒤 theme 값을 조건부 렌더링을 통해 설정해준다.
 
하위 컴포넌트인 Theme 컴포넌트를 통해 테마를 변경할 것이기 때문에 테마와 관련된 ThemeContext 를 생성하여 _app.tsx 에 있는 JSX 항목들을 감싸주고 생성했던 useTheme 를 통해 ThemeProvider 에는 theme 값을, ThemeContext 에는 Theme 컴포넌트에서 사용할 theme, toggleTheme 값을 적용시켜주었다.
 
테마를 토글 형식으로 설정할 수 있는 Theme 컴포넌트를 생성하였다.
ThemeContext 를 통해 _app.tsx 에서 전달해준 값들을 받아서 theme 를 통해 보여줄 아이콘을 조건부 렌더링 하였고, 버튼의 클릭 이벤트에 toggleTheme 를 적용시켜 클릭하는 경우 토글 이벤트가 발생하도록 적용하였다.
useTheme - theme 의 기본값이 빈 문자열이라 페이지 초기에 깜빡이는 것처럼 보이기 때문에 조건부 렌더링을 통해 값이 존재하는 경우에만 버튼을 보여주도록 하였다.
 
기능 확인이 완료되면 테마 구분이 필요한 항목에 _app.tsx 에서 전달받은 theme 를 적용시켜준다.
 

 
참고