🍣

【React】Contect APIを使ってダークテーマ切り替え

2023/04/16に公開

ライブラリ類はCDNで読み込んでいるので、コピペで動きます

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>React Theme Toggle</title>
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
      rel="stylesheet"
    />
    <script
      crossorigin
      src="https://unpkg.com/react@17/umd/react.production.min.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"
    ></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/babel">
      const { createContext, useContext, useState } = React;

      // テーマ用のコンテキストを作成
      const ThemeContext = createContext();

      // テーマプロバイダーコンポーネント
      const ThemeProvider = ({ children }) => {
        const [theme, setTheme] = useState("light");

        const toggleTheme = () => {
          setTheme((prevTheme) => (prevTheme === "light" ? "dark" : "light"));
        };

        return (
          <ThemeContext.Provider value={{ theme, toggleTheme }}>
            {children}
          </ThemeContext.Provider>
        );
      };

      // カスタムフック
      const useTheme = () => {
        const context = useContext(ThemeContext);
        if (!context) {
          throw new Error("useTheme must be used within a ThemeProvider");
        }
        return context;
      };

      // アプリケーションコンポーネント
      const App = () => {
        const { theme, toggleTheme } = useTheme();

        return (
          <div
            className={`container ${
              theme === "dark" ? "bg-dark text-white" : ""
            }`}
            style={{ height: "90vh" }}
          >
            <h1 className="my-4">React Theme Toggle</h1>
            <button
              className={`btn ${theme === "dark" ? "btn-light" : "btn-dark"}`}
              onClick={toggleTheme}
            >
              Toggle Theme
            </button>
          </div>
        );
      };

      // レンダリング
      ReactDOM.render(
        <ThemeProvider>
          <App />
        </ThemeProvider>,
        document.getElementById("root")
      );
    </script>
  </body>
</html>

Discussion