🌙

Reactのinline styleでダークモードを実装してみた

2024/01/08に公開

はじめに

今回はReactでライトモード・ダークモードを切り替える機能を実装しました。完成イメージは以下の通りです。この中から今回実装した部分についてご紹介します。

注意点

今回作成したアプリでは以下のようなinline styleの書き方でスタイルを記載しています。他の書き方では今回の方法は使えない場合があるのでご注意ください。

<div style={{ backgroundColor: '#FFFFFF' }}>
  sample
</div>

対象の読者

・スタイルをinline styleで記載している方
・useState, useContextの使い方を把握している方

実装内容

ライトモード・ダークモードの状態保持とそれぞれのモードで使用する色を保持するContextを作成しました。

DarkModeProvider.tsx
export const DarkModeProvider: React.FC<IProps> = ({ children }) => {

  const [isDarkMode, setIsDarkMode] = useState(false);
  const [color, setColor] = useState({});

  const handleDarkMode = (value: boolean) => {
    setIsDarkMode(value);
  };

  useEffect( () => {
    if (isDarkMode) {
      setColor({
        background: '#000000',
      });
      return;
    }

    setColor({
      background: '#FFFFFF',
    });
  }, [isDarkMode]);

  return (
    <DarkModeContext.Provider value={{color, isDarkMode, handleDarkMode}}>
      {children}
    </DarkModeContext.Provider>
  );
};

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



isDarkModetrueの場合をダークモードとしており、
・ダークモード:背景が黒(#000000)
・ライトモード:背景が白(#FFFFFF)
になるイメージです。

DarkModeProvider.tsxより抜粋
useEffect( () => {
  if (isDarkMode) {
    setColor({
      background: '#000000',
    });
    return;
  }

  setColor({
    background: '#FFFFFF',
  });
}, [isDarkMode]);



後は以下のように呼び出せばモードに対応した背景色が表示されます。

Sample.tsx
import {useDarkModeContext} from '@/scripts/Provider/DarkModeProvider';

export const Sample: FC<IProps> = () => {
  const darkModeContext = useDarkModeContext();

  return (
    <div style={{ backgroundColor: darkModeContext.color.background }}>
      sample
    </div>
  );
};



ライトモード・ダークモードの切り替えについては、切り替えを行うコンポーネントで以下のように呼び出して行っています。

Sample.tsx
import {useDarkModeContext} from '@/scripts/Provider/DarkModeProvider';

export const Switch: React.FC<IProps> = () => {
  const darkModeContext = useDarkModeContext();

  return (
    <button onClick={() => darkModeContext.handleDarkMode(!darkModeContext.isDarkMode)}>
      モードの切り替え
    </button>
  );
};

おわりに

以上の構成でライトモード・ダークモードを切り替える機能を実装しました。
モードを切り替えるたびに丸々再レンダリングが行われるのが悩ましいところですが、今回作成したような小規模なアプリでは特にパフォーマンスへの影響は無かったので目をつぶっています。

Discussion