ContextAPI 를 이용한 다크모드

taeyooooon·2023년 3월 29일
0
post-thumbnail

요즘은 너무 당연한 기능 중 하나인 다크모드를 아직 구현해본 적이 없어서
다크모드 적용 방법을 공부해보았는데
Context API를 이용해 간단하게 구현할 수 있어서 공부를 해보았다.

Context API 구현

먼저 다크모드 Context를 생성해서

import { createContext, useContext, useEffect, useState } from 'react';

const DarkModeContext = createContext();

const updateDarkMode = (darkMode) => {
  if (darkMode) {
    localStorage.theme = 'dark';
    document.documentElement.classList.add('dark'); // html 클래스 추가
  } else {
    localStorage.theme = 'light';
    document.documentElement.classList.remove('dark');
  }
};

export function DarkModeProvider({ children }) {
  const [darkMode, setDarkMode] = useState(false);

  const toggleDarkMode = () => {
    updateDarkMode(!darkMode);
    setDarkMode(!darkMode);
  };

  useEffect(() => {
    const isDark =
      localStorage.theme === 'dark' ||
      (!('theme' in localStorage) &&
        window.matchMedia('(prefers-color-scheme: dark)').matches); 
    // 사용자 기종 다크모드 확인
    setDarkMode(isDark);
    updateDarkMode(isDark);
  }, []);

  return (
    <DarkModeContext.Provider value={{ darkMode, toggleDarkMode }}>
    // value에 사용하고자 하는 값들을 담아줌 => { darkMode, toggleDarkMode }
      {children}
    </DarkModeContext.Provider>
  );
}

export const useDarkMode = () => useContext(DarkModeContext);

다크모드를 적용하고자 하는 최상위 컴포넌트를 Provider로 감싸주고

function App() {
  return (
    <DarkModeProvider>
      <Components1/>		// 적용하고자 하는 컴포넌트들
	  <Components2/>
    </DarkModeProvider>
  );
}

다크모드 토글버튼을 사용하고자 하는 곳에서 사용해 호출

export default function Header({ filters, filter, onFilterChange }) {
  const { darkMode, toggleDarkMode } = useDarkMode();

  return (
    <header className={styles.header}>
      <button onClick={toggleDarkMode} className={styles.toggle}>
        // 다크모드에 따른 토글 버튼 생성
        {!darkMode && <HiMoon />}
        {darkMode && <HiSun />}
        
      </button>
         
      <...>
        
    </header>
  );
}

그러면 html 클래스명 토글이 작동하고

CSS Variable 사용

CSS에서 자주사용하는 색상들을 변수로 지정한 뒤
다크모드일때 색상변수를 재할당해 사용하는 방식으로 사용하면 된다!

:root {
  --color-bg-dark: #f5f5f5;
  --color-bg: #fdfffd;
  --color-grey: #d1d1d1;
  --color-text: #11142c;
  --color-accent: #39c2b2;
  --color-white: #fff;
  --color-scrollbar: #637b87;
}

html.dark {
  --color-bg-dark: #1a1c35;
  --color-bg: #22243b;
  --color-grey: #3f3d3d;
  --color-text: #fdfffd;
}

참고한 글

https://velog.io/@velopert/velog-dark-mode
https://tailwindcss.com/docs/dark-mode

profile
응애🐣 프론트엔드

0개의 댓글