当サイトは、アフィリエイト広告を利用しています
CSS in JSのEmotionをReact x TypeScriptで使う際に
propsでemotionのstyle(cssprops)を受け取る方法をまとめる。
Emotionではstyleの定義方法として下記の3つがある
個人的には「StringStyles」が一番使いやすいので
「StringStyles」を使っている。
ので、今回はEmotionのStringStylesをTypeScriptで使う方法を メモしておく。
「ObjectStyle」や「styled-component」の基本的な使い方や
「StringStyles」の実装サンプルについては下記記事で紹介しています。
※javascriptでの実装です。
Emotionのstyleをpropsでコンポーネントにで受け取るためには
Emotionのstyleの定義をしてやる必要がある。
javascriptの場合と比較してみる。
Emotionでcsspropsでstringstyleの定義を使う場合は
javascriptでは下記のようになる。
import { css} from "@emotion/react";//コンポーネントconst EmotionPropsComponent1 = (props) => {//emotionのstyleを受け取るconst { cssStyleFunc } = props;return <h1 css={cssStyleFunc}>Emotion_cssprops_javascript</h1>;};export function App() {//emotionでstyle定義const emostyle = () => [css`color: blue;`];return (<div><EmotionPropsComponent1 cssStyleFunc={emostyle} /></div>);}
上記のjavascriptをTypeScriptで書くと
//コンポーネントconst EmotionPropsComponent1 = (props) => {//emotionのstyleを受け取るconst { cssStyleFunc } = props;return <h1 css={cssStyleFunc}>Emotion_cssprops_javascript</h1>;};
propsで型定義を書けといういエラーになる。
※anyを書けばエラーは消えるが、それだとTypeScritpを使う意味がないので
エラーを消すためには、Emotionのstyleの型を定義する必要がある。
Emotionのstyleの型は下記のようになっている
~export interface SerializedStyles {name: stringstyles: stringmap?: stringnext?: SerializedStyles}~
SerializedStylesをimportして使うことでエラーを解消できる。
/** @jsxImportSource @emotion/react */import { css, SerializedStyles } from "@emotion/react";//emotionのstyleの型定義type cssStyleFunc = (str?:string) => SerializedStyles[]//propsの定義type EmProps = {cssStyleFunc: cssStyleFunc;};//コンポーネントconst EmotionPropsComponent1 = (props: EmProps) => {//emotionのstyleを受け取るconst { cssStyleFunc } = props;return <h1 css={[cssStyleFunc()]}>Emotion_cssprops_TypeScript</h1>;};export function App() {//emotionでstyle定義const emostyle: cssStyleFunc = () => [css`color: blue;`];return (<div><EmotionPropsComponent1 cssStyleFunc={emostyle} /></div>);}
実装サンプルを載せます
Emotionのcsspropsの渡し方はいろいろとパターンがあるので
パターンごとのサンプルを載せる。
個人的にはEmotionを使う時にはこの書き方をする。
※上記の「実装サンプル」もこの方式で書いています。
import { css, SerializedStyles } from "@emotion/react";//emotionのstyleの型定義type cssStyleFunc = (str?: string) => SerializedStyles[];//propsの定義type EmProps = {cssStyleFunc: cssStyleFunc;};
受け取る側も配列で受け取るようにする
//コンポーネントconst EmotionPropsComponent1 = (props: EmProps) => {//emotionのstyleを受け取るconst { cssStyleFunc } = props;//インラインでスタイル追加return <h1 css={[cssStyleFunc(),css`background:red`]}>Emotion_cssprops_TypeScript</h1>;};
「Emotionのstyleの配列を返す関数で受け取る場合」と同じ型定義を使う 実装サンプルをのせときます
関数ではなく配列で受け取ることもできる。
/** @jsxImportSource @emotion/react */import { css, SerializedStyles } from "@emotion/react";//propsの定義type EmProps = {cssStyleArray: SerializedStyles[];};//コンポーネントconst EmotionPropsComponent1 = (props: EmProps) => {//emotionのstyleを受け取るconst { cssStyleArray } = props;return <h1 css={[cssStyleArray]}>Emotion_cssprops_TypeScript</h1>;};export function App() {//Emotionのstyleの配列を受け取る場合const emostyle: SerializedStyles[] = [css`color: white;`];//スタイル追加emostyle.push(css`background-color:blue`)return (<div><EmotionPropsComponent1 cssStyleArray={emostyle} /></div>);}
関数や配列ではなく、SerializedStylesのままでも受け取ることはできる。
/** @jsxImportSource @emotion/react */import { css, SerializedStyles } from "@emotion/react";//propsの定義type EmProps = {cssStyleArray: SerializedStyles;};//コンポーネントconst EmotionPropsComponent1 = (props: EmProps) => {//emotionのstyleを受け取るconst { cssStyleArray } = props;return <h1 css={cssStyleArray}>Emotion_cssprops_TypeScript</h1>;};export function App() {//Emotionのstyleを受け取る場合const emostyle: SerializedStyles = css`color: blue;`;return (<div><EmotionPropsComponent1 cssStyleArray={emostyle} /></div>);}
サンプルのせときます
Emotionのcsspropsではいろいろな書き方ができるので
実現したい仕様に合わせて、自分の使いやすい使い方をすれば
良いと思う。
Emotionの使い方のサンプルについては下記記事でも紹介しているので
当記事で合わせて見ればTypeScript対応できると思う。