다들 포트폴리오 웹사이트 하나정도는 가지고 있는거 같아서(?) 나도 만들어 보기로 했다.
사실 이 블로그를 쓰는 시점에서 대략 완료를 한 상태이다.
포트폴리오를 만들면서 새로 접한 개념이나 처음 구현해본 기능들의 기록을 남겨두려고 한다.
라이트모드/ 다크모드
찾아보니 다크모드 구현을 할 때 보통은 Context API의 ThemeProvider를 사용한다고 한다.
몇 가지 블로그를 둘러보다가 조금 더 간단하게 다크모드를 구현하는 블로그를 발견하여 이 방식대로 다크모드를 구현해보기로 했다.
https://kyounghwan01.github.io/blog/etc/CSS/dark-mode/
react로 다크 모드(dark mode) 만드는 법, styled-components, css, scss, theme
react로 다크 모드(dark mode) 만드는 법, styled-components, css, scss, theme
kyounghwan01.github.io
핵심은 가장 상위 html 태그에 클래스를 주는 방식으로 다크모드와 라이트모드를 변경하는 것이다.
const handleMode = () => {
if (mode === "dark") {
setMode("light");
document.getElementsByTagName("html")[0].classList.remove("dark-mode");
localStorage.setItem("mode", "light");
} else {
setMode("dark");
document.getElementsByTagName("html")[0].classList.add("dark-mode");
localStorage.setItem("mode", "dark");
}
};
위의 함수가 실행되면 다크 모드로 변경되고, 가장 상위 태그인 html 태그에 dark-mode class가 추가되고, state가 dark로 바뀐다. 그리고 새로고침할 때도 다크모드를 유지하기 위해 로컬 스토리지를 활용하여 다크모드 상태를 저장해둔다.
반대로 다크모드에서 위 함수가 실행되면 같은방식으로 라이트모드가 된다.
헤더 부분 아이콘을 클릭하면 다크모드로 변경되도록 Onclick 이벤트 리스너로 위의 함수를 추가한다.
const [mode, setMode] = useState<"dark" | "light">("light");
...
<button onClick={handleMode}>
{mode === "light" ? <MdDarkMode /> : <MdLightMode />}
</button>
mode는 아이콘을 변경하기 위한 상태로 현재 모드에 따라 다른 아이콘을 렌더링 하도록 삼항연산자 사용했다.(아이콘은 react-icons 라이브러리를 사용했다.)
새로고침 할 때도 모드를 유지할 수 있도록 첫 렌더링 때 useEffect에서 로컬 스토리지의 mode를 불러올 수 있도록 코드를 작성해준다.
useEffect(() => {
const localMode = localStorage.getItem("mode") as "dark" | "light" | null;
if (localMode) setMode(localMode);
if (localMode === "dark") {
document.getElementsByTagName("html")[0].classList.add("dark-mode");
}
}, []);
만약 다크모드가 저장되어있으면 바로 다크모드로 바꿔준다.
이제 모드에 따라 다른 색상을 적용하도록 GlobalStyle에 아래처럼 모드 별 색상을 적용한다.
:root {
--background-color : #F8F6F4;
--background-color2 : #CAEDFF;
--border-color : black;
// ...
}
.dark-mode {
--background-color : #0E2954;
--background-color2 : #1F6E8C;
--border-color : white;
// ...
}
css 변수를 지정하여 같은 변수명으로 :root에는 라이트모드에서 사용할 색상을, .dark-mode에서는 다크모드에서 사용할 색상을 쌍으로 선택해주었다.

생각보다 간단하게 다크모드가 구현되는 것 같다!
'토이 프로젝트 > 포트폴리오 웹사이트' 카테고리의 다른 글
프로젝트 컴포넌트 with 캐러셀 UI (1) | 2023.10.07 |
---|---|
아코디언, 탭박스 UI 구현 (0) | 2023.10.02 |
헤더 스크롤 이벤트 및 스로틀링 (0) | 2023.09.27 |
댓글