当サイトは、アフィリエイト広告を利用しています
ReactでEmotionのstyleを動的(ボタン押下などのevent)で
動的に変更する方法をメモしておく。
Reactでの基本的なEmotionの使い方は下記の記事で紹介しています
Emotionは関数で定義すれば引数の値によって動的にスタイルを変更することができるが
ボタンクリックなどのイベントでスタイルを変更したい場合はReactHooksのuseStateを
使って再レンダリングをさせる必要がある。
/** @jsxImportSource @emotion/react */import { css } from "@emotion/react";import "./styles.css";import { useState } from "react";export default function App() {console.log("useState");const [color, setColor] = useState("blue");const handleClick=()=>{console.log("handleClick");setColor((prev) => (prev === "red" ? "blue" : "red"))}return (<div className="App">{console.log("レンダー")}<h1 css={[style(color)]}>Hello CodeSandbox</h1><h2>react + emotion</h2><buttononClick={()=>handleClick()}>changeColor</button></div>);}const style = (color) => [css`color: ${color};`];
reactのuseStateとemotionを使ってタグ選択するサンプルを作ってみる
/** @jsxImportSource @emotion/react */import { css } from "@emotion/react";import { useState } from "react";export default function App() {// タグ初期値const array = Array.of("java","javascript","gatsby","react","css","emotion");// 選択中タグのstateconst [selectedTag, selectTag] = useState([]);// タグ選択処理const push = (e) => {e.preventDefault();// タグが既に選択済かチェックするconst check = selectedTag.find((tag) => {return tag === e.target.id;});if (!check) {//未選択の場合は追加selectTag((selected) => [...selected, e.target.id]);} else {// 選択済の場合は削除// filterで選択したタグ以外のlistを作り直すselectTag((selected) => selected.filter((tag) => tag !== e.target.id));}};return (<div className="App"><h1>Hello CodeSandbox</h1><h2>タグ</h2><div css={[tagsGrid]}>{array.map((val, i) => (<buttonkey={i}id={val}css={[grigItem(selectedTag, val)]}onClick={(e) => push(e)}>{val}</button>))}</div></div>);}const tagsGrid = () => [css`display: grid;grid-template-columns: repeat(3, minmax(100px, 10%));grid-auto-rows: 50px;justify-content: center;align-items: center;gap: 10px;border: 1px solid black;margin: auto;`];// タグ選択時のスタイル変更const grigItem = (selectTag, select) => {// 選択したタグが既に選択済かチェックconst count = selectTag.filter((selected) => select === selected);// 選択してない場合はスタイル追加if (count.length !== 0) {return [css`background-color: red;`];}};
Emotionでjavascriptで書いたcssを動的に変更するためには
再レンダーさせる必要がある。
ReactではEmotionを使う時はレンダーされるタイミング等を考慮していく必要があることが
わかったので良かった。
Emotionの基本的な使い方は下記で紹介してます!
ちなみにEmotionもuseStateも使わずに直接、DOMをいじることでも
最初のサンプルと同じ動作をさせることができるが、React的にはよろしくないと思う。
一応、サンプルの載せる。