Hooks를 사용하여 React 앱에 다크 모드를 추가하고 로컬 저장소에 저장하는 간단한 방법

이 기사에서는 최근에 React project 에서 구현한 다크/라이트 모드 토글에 대한 접근 방식을 공유할 것입니다. 이는 초보자도 쉽게 이해할 수 있다고 생각합니다.



먼저 <span> 요소를 내 App.tsx 파일에 추가합니다. 원하는 대로 <button> , <div> 가 될 수 있습니다. 이는 다크/라이트 모드의 스위치 역할을 합니다.

import React, { useEffect, useState } from 'react';

function App() {
    return (
      <div className='container'>
        <span className='mode-switch'></span>
        {/* my other elements */}
      </div>
    )
}

export default App;



그런 다음 몇 가지 기본 스타일을 추가합니다. 나는 스위치가 내 컨테이너 요소의 오른쪽 상단 모서리에 절대적으로 배치되는 것을 선호합니다.

.container {
  position: relative;
  max-width: 1400px;
  padding: 40px 30px;
}

.mode-switch {
  position: absolute;
  right: 15px;
  top: 15px;
  font-size: 11px;
  cursor: pointer;
  transition: color 0.2s ease-in-out;

  &:hover {
    color: #50bbf1;
  }
}



App 구성 요소로 돌아가서 useState 후크를 추가합니다. mode 변수와 setMode 함수를 정의합니다. 지금은 기본 모드를 useState 후크 내부의 'light'로 전달합니다.
그런 다음 스위치에 onClick 이벤트를 추가하고 이 이벤트에서 조건부 매개변수를 사용하여 setMode 함수를 호출합니다.
이 기능은 밝은 경우 모드를 어둡게 설정하고 그 반대의 경우도 마찬가지입니다.
또한 동적으로 스위치에 텍스트 콘텐츠를 추가합니다.

function App() {
    const [mode, setMode] = useState('light'); 

    return (
      <div className='container'>
        <span 
           className='mode-switch'
           onClick={() => 
             setMode(mode === 'dark' ? 'light' : 'dark')
           }
        >
           {mode === 'dark' ? 'Light mode' : 'Dark mode'}
        </span>
      </div>
    )
}



다음 단계는 useEffect 후크를 사용하여 모드 간 전환 및 관련 스타일 추가/제거입니다.
어두운 모드로 전환되면 단순히 '.dark' 클래스를 <body>에 추가하고 선택한 모드가 밝은 경우 제거합니다.[mode]useEffect의 두 번째 매개변수로 전달합니다. 이는 '모드' 변경의 부작용으로 작동하기 때문입니다.

function App() {
    const [mode, setMode] = useState('light'); 

    useEffect(() => {
      if (mode === 'dark') {
        document.body.classList.add('dark');
      } else {
        document.body.classList.remove('dark');
      }
    }, [mode]);

    return (



그런 다음 필요한 스타일을 추가하여 배경색을 검은색으로 만들고 원래 색상이 지정되지 않았고 기본적으로 검은색인 경우 모든 텍스트를 흰색으로 바꿉니다.

.dark {
  background-color: #222;
  color: #f5f5f5; 
}



어두운 모드에서 <body> 이외의 다른 요소의 스타일을 지정하기 위해 & 선택기를 사용합니다.
'기본 버튼' 클래스가 있는 버튼이 있다고 가정해 보겠습니다. 다크 모드가 활성화되었을 때 색상과 배경색을 변경하고 싶습니다.

.primary-button {
  // default style: black button with white text
  background-color: #222;
  color: #f5f5f5;

  // dark mode style: white button with black text 
  .dark & {
    background-color: #f5f5f5;
    color: #222;
  }
}



이제 선택한 모드를 로컬 저장소에 저장하여 앱을 재설정해도 선택한 모드가 유지되도록 할 차례입니다. 이를 달성하기 위해 먼저 useEffect 후크로 돌아가 다음 코드를 포함합니다.

useEffect(() => {
  if (mode === 'dark') {
     document.body.classList.add('dark');
  } else {
     document.body.classList.remove('dark');
  }
  localStorage.setItem('mode', mode); // mode saved to local storage
}, [mode]);



그런 다음 위로 올라가 글로벌 수준에서 getDefaultMode라는 유틸리티 함수를 만듭니다. 이 함수는 로컬 저장소에서 저장된 모드를 가져오고 앱이 시작될 때 그에 따라 기본 모드를 결정합니다. 이전에 어두운 모드를 선택하지 않은 경우 기본 모드는 '밝음'입니다.

function getDefaultMode() {
  const savedMode = localStorage.getItem('mode');
  return savedMode ? savedMode : 'light';
}



이제 이전에 내 useState 구성 요소에 추가한 App 후크 내에서 이 함수를 호출해야 합니다. light 매개변수를 getDefaultMode 함수로 바꿉니다.

const [mode, setMode] = useState(getDefaultMode());


최종 코드는 결국 다음과 같습니다.

import React, { useEffect, useState } from 'react';

function getDefaultMode() {
  const savedMode = localStorage.getItem('mode');
  return savedMode ? savedMode : 'light';
}

function App() {
    const [mode, setMode] = useState(getDefaultMode()); 

    useEffect(() => {
      if (mode === 'dark') {
        document.body.classList.add('dark');
      } else {
        document.body.classList.remove('dark');
      }
      localStorage.setItem('mode', mode);
    }, [mode]);

    return (
      <div className='container'>
        <span 
           className='mode-switch'
           onClick={() => 
             setMode(mode === 'dark' ? 'light' : 'dark')
           }
        >
           {mode === 'dark' ? 'Light mode' : 'Dark mode'}
        </span>
        {/* my other elements */}
      </div>
    )
}

좋은 웹페이지 즐겨찾기