프로젝트의 UI를 구상하며 웹에 사용할 색상을 정하던 중 예전부터 적용해보고 싶었던 다크 모드를 구현하게 되었다.

전역 관리 방법을 생각해보며 redux, recoil 등의 선택지도 있었지만 전역으로 관리할 값이 크게 많지 않을 것이라 생각하여 React 내장 기본 hook인 useContext를 사용해보기로 했다.

추가적으로 다크 모드에서는 모드의 상태와 theme 값이 정해져 있는 값으로 토글 되는 기능 밖에 존재하지 않아 useReducer는 사용하지 않고 useState로 간단하게 토글 로직을 구현했다.

다크 모드를 적용하면서 만났던 오류들과 해결 방법이다.

state는 변경되지만 스타일이 바뀌지 않는 문제, 재랜더링 후 초기 값이 보이는 문제

문제: 브라우저의 개발자 도구에서는 context의 변경이 확인되었지만 스타일이 변경되지 않았고 새로 고침이 되어야 모드 값에 따른 스타일이 적용되었고 추가적으로 재랜더링되고 잠깐 초기 값 스타일이 보이는 문제가 발생.

해결: theme 값을 자바스크립트 변수가 아닌 state에 저장해서 관리하는 방식으로 변경, useEffect에서 useLayoutEffect로 변경.

모드 전환 시 랜더링이 불필요하게 두 번 되는 문제

문제: 개발자 도구의 콘솔에서 불필요한 랜더링 2배로 발생. twilightTheme 객체는 DarkModeContext.Provider 컴포넌트가 렌더링될 때마다 새로운 객체로 생성된다. 이로 인해 다크모드 전환 시마다 새로운 객체가 만들어지면서 불필요한 렌더링이 발생.

해결: useMemo 를 사용하여 twilightTheme 객체를 메모이제이션하여 isDarkMode 값이 변경될 때만 새로운 객체를 생성하도록 수정.