Reactでダークモードを実装する方法

Reactでダークモードを実装する方法

ダークモードは、ユーザーにとって目に優しく、エネルギー効率を高めるため、現代のウェブアプリケーションで重要な機能となっています。Reactを使ってダークモードを実装する方法を、CSSカスタムプロパティやprefers-color-schemeメディアクエリを活用して解説します。

1. ダークモードの基本概念

ダークモードは、通常のライトモードとは逆に、背景色を暗くして、テキストやアイコンを明るくするUIテーマです。ユーザーが選択したテーマに基づいてアプリケーションのスタイルを動的に切り替えることができます。

2. CSSでダークモードを切り替える方法

ダークモードを実現するために、まずはCSSでprefers-color-schemeメディアクエリを使用します。これにより、ユーザーのシステム設定に合わせてスタイルを適用できます。

@media (prefers-color-scheme: dark) {
  body {
    background-color: #121212;
    color: #ffffff;
  }
}

3. Reactでダークモードの状態を管理する

Reactでは、状態管理を用いてダークモードの切り替えを行います。useStateを使ってテーマの状態を管理し、useEffectを使ってテーマ変更をローカルストレージに保存します。

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

const App = () => {
  const [isDarkMode, setIsDarkMode] = useState(false);

  useEffect(() => {
    const savedMode = localStorage.getItem('theme');
    if (savedMode === 'dark') {
      setIsDarkMode(true);
    }
  }, []);

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

  return (
    <button onClick={() => setIsDarkMode(!isDarkMode)}>
      Toggle Dark Mode
    </button>
  );
};

4. CSSカスタムプロパティを使ってテーマを管理する

CSSカスタムプロパティ(変数)を使用すると、テーマの色を一元管理しやすくなります。例えば、ダークモード時に背景色やテキスト色を変更する際に便利です。

:root {
  --bg-light: #ffffff;
  --bg-dark: #121212;
  --text-light: #000000;
  --text-dark: #ffffff;
}

body {
  background-color: var(--bg-light);
  color: var(--text-light);
}

body.dark {
  background-color: var(--bg-dark);
  color: var(--text-dark);
}

5. ダークモードのテーマ切替用ボタンの作成

ユーザーがダークモードとライトモードを手動で切り替えられるように、ボタンを作成します。useStateを使ってモードを管理し、ボタンのクリックでモードを切り替えます。

<button onClick={() => setIsDarkMode(!isDarkMode)}>
  {isDarkMode ? 'Switch to Light Mode' : 'Switch to Dark Mode'}
</button>

6. ダークモードの初期設定をローカルストレージに保存する

テーマ設定をローカルストレージに保存して、ユーザーがアプリを再訪問したときに、前回のテーマを保持できるようにします。

useEffect(() => {
  const savedMode = localStorage.getItem('theme');
  if (savedMode === 'dark') {
    setIsDarkMode(true);
  }
}, []);

7. ダークモードのアニメーションを追加する

ダークモードの切り替えを滑らかに見せるために、CSSでトランジションを追加することができます。

body {
  transition: background-color 0.3s ease, color 0.3s ease;
}

8. ダークモードに対応したアイコンや画像の切り替え

ダークモードに切り替えたときに、アイコンや画像も適切に変更したい場合、CSSのcontentプロパティを使って変更することができます。

body.dark .logo {
  content: url('logo-dark.png');
}

body .logo {
  content: url('logo-light.png');
}

9. ダークモード対応のフォント選択

ダークモードに合わせてフォントの色やスタイルを変更することで、視認性が向上します。特にダーク背景に明るいフォントカラーを使用することが一般的です。

body {
  font-family: 'Roboto', sans-serif;
}

body.dark {
  font-family: 'Arial', sans-serif;
}

10. ダークモードをテーマライブラリで簡単に実装する

テーマ管理をより簡単に行いたい場合、styled-componentsemotionなどのテーマライブラリを使用してダークモードを実装することができます。

import styled, { ThemeProvider } from 'styled-components';

const lightTheme = {
  background: '#ffffff',
  color: '#000000',
};

const darkTheme = {
  background: '#121212',
  color: '#ffffff',
};

const App = () => {
  const [isDarkMode, setIsDarkMode] = useState(false);

  return (
    <ThemeProvider theme={isDarkMode ? darkTheme : lightTheme}>
      <div style={{ background: 'var(--bg)', color: 'var(--text)' }}>
        <button onClick={() => setIsDarkMode(!isDarkMode)}>
          Toggle Dark Mode
        </button>
      </div>
    </ThemeProvider>
  );
};

11. ダークモードの状態をContextで管理する

ダークモードの状態をReact Contextを使って全体で管理することができます。これにより、アプリケーションのどこからでもモード切替が可能になります。

const ThemeContext = React.createContext();

const ThemeProvider = ({ children }) => {
  const [isDarkMode, setIsDarkMode] = useState(false);
  return (
    <ThemeContext.Provider value={{ isDarkMode, setIsDarkMode }}>
      {children}
    </ThemeContext.Provider>
  );
};

const App = () => {
  const { isDarkMode, setIsDarkMode } = useContext(ThemeContext);

  return (
    <button onClick={() => setIsDarkMode(!isDarkMode)}>
      {isDarkMode ? 'Switch to Light Mode' : 'Switch to Dark Mode'}
    </button>
  );
};

12. ダークモードとアクセシビリティの考慮

ダークモードを導入する際は、ユーザーの視認性を確保するために、十分なコントラスト比を保ち、アクセシビリティを考慮した配色を選択することが重要です。