当サイトは、アフィリエイト広告を利用しています
ReactでEmotionのThemeProviderを使って簡易darkmodeを
実装しtheme切り替えの動きを確認してみる。
EmotionのThemeProviderとはThemeProviderコンポーネントにpropsでオブジェクトを渡すと
ThemeProviderコンポーネントでラップしたコンポーネント内でpropsに渡したオブジェクトを
参照することができるようになる。
※hooksのuseContextみたいなイメージ。
ThemeProviderを使って簡易darkmodeを実装し、動きを確認する
動作確認環境は下記参照
"dependencies": {"@emotion/react": "11.8.2","react": "18.0.0","react-dom": "18.0.0","react-scripts": "4.0.0"},"devDependencies": {"@babel/runtime": "7.13.8"},
themeProviderを使ってComponentA,ComponentB,ComponentCの
themeを切り替える
/** @jsxImportSource @emotion/react */import "./styles.css";import ComponentA from "./componentA";import ComponentB from "./componentB";import ComponentC from "./componentC";import { ThemeProvider } from "@emotion/react";import React, { useState } from "react";// テーマを定義する// ライトテーマconst lightTheme = {mode: "light",background: "#ffffff",color: "#000000"};// ダークテーマconst darkTheme = {mode: "dark",background: "#222639",color: "#f0f5fa"};export default function App() {// テーマをstateで保持const [theme, setTheme] = useState(darkTheme);// テーマを切り替える関数const changeTheme = (mode) => {if (mode === "dark") {return lightTheme;} else {return darkTheme;}};return (<div className="App"><h1>Hello CodeSandbox</h1><h2>React + Emotion + ThemeProvider</h2><ThemeProvider theme={theme}><ComponentA /><ComponentB /><ComponentC /></ThemeProvider><button onClick={() => setTheme(({ mode }) => changeTheme(mode))}>Theme change</button></div>);}
ラップされているコンポーネントでThemeProviderに渡したthemeを
参照することができる。
参照する方法としては下記の2つあがる
ThemeProviderに渡したpropsのthemeを参照してスタリングを行うことで
propsが切り替わるとthemeが切り替わるようになる。
/** @jsxImportSource @emotion/react */import { css } from "@emotion/react";const ComponentA = () => {return <div css={[style]}>hello ComponentA</div>;};export default ComponentA;// themeProviderに渡したthemeを暗黙的にpropsから参照できるconst style = (theme) => {return [css`color: ${theme.color};background-color: ${theme.background};`];};
EmotionのuseTheme()メソッドを使って明示的にthemeを取得することもできる。
/** @jsxImportSource @emotion/react */import { css } from "@emotion/react";import { useTheme } from "@emotion/react";const ComponentB = () => {//theme取得const theme = useTheme();const style = () => {return [css`color: ${theme.color};background-color: ${theme.background};`];};return <div css={[style]}>hello ComponentB</div>;};export default ComponentB;
動作を確認する
emotionを使用している場合はThemeProviderを使うと簡単にテーマを切り替えることができる
ことがわかった。
今回はThemeProviderの動きを見るため最小限の実装しかしていないため
hooksはuseStateしか使っていないが、実際ホームページ等で使用する場合は
hooksのuseContextも使う必要がある。
当ブログのdarkmodeはこの方式で実装してます。
詳しくは下記記事にまとめています。