LoginSignup
10
3

More than 1 year has passed since last update.

【React】propsでemotionのスタイルを受け取る際の型定義

Last updated at Posted at 2021-11-11

はじめに

propsでemotionスタイルを受け取る際に、propsに対して型定義を行う際に
気づいたことがあったので学習記録としてメモ

環境

"react": "^17.0.1"
"@emotion/react": "^11.4.1"

emotionのスタイルの型

emotionのスタイルの型はemotionで定義されています。
SerializedStylesをimportして型定義してあげるとpropsでemotionのスタイルを受け取ることができます。

node_modules/@emotion/utils/types/index.d.ts
// Definitions by: Junyoung Clare Jang <https://github.com/Ailrun>
// TypeScript Version: 2.2

~~ 省略 ~~

export interface SerializedStyles { // <= これ
  name: string
  styles: string
  map?: string
  next?: SerializedStyles
}

いままでの型定義例

Text.tsx

import { SerializedStyles, jsx, css } from '@emotion/react'

type Props = {
  cssStyle: SerializedStyles
}

export const Text = (props: Props) => {
  const { cssStyle } = props

  const textStyle = css`
    color: red;
    ${cssStyle}
  `
  return <p css={textStyle}>style定義</p>
}

TextBox.tsx

import { css } from '@emotion/react'
import { Text } from './Text'

const TextBox = () => {
  const textStylePrimary = css`
    border: 1px solid blue;
  `

  const textStyleSecondary = css`
    border: 2px solid black;
  `

  return (
    <div>
      <Text cssStyle={textStylePrimary} />
      <Text cssStyle={textStyleSecondary} />
    </div>
  )

}

気づいたこと

SerializedStylesですべてprops型定義するとEmotionに依存してるのではということに気づく。
* jsxでcss propsを使っている時点で依存していますが、それはまた別の機会に修正します。

SerializedStylesをType共通で定義してあげて、変更に耐えうるように変更する

変更版

Type定義用のファイルで適応させます。
そうすると、もしcss in jsライブラリを置き換えた時に、定義ファイルの中身を変えるだけで型定義は変えれるので
今後はこの形で良さそう

types/style.ts
import { SerializedStyles } from '@emotion/react'
export type StyleType = SerializedStyles
Text.tsx

import { jsx, css } from '@emotion/react'
import { StyleType } from '../types/style'

type Props = {
  cssStyle: StyleType
}

export const Text = (props: Props) => {
  const { cssStyle } = props

  const textStyle = css`
    color: red;
    ${cssStyle}
  `
  return <p css={textStyle}>style定義</p>
}

TextBox.tsx

import { css } from '@emotion/react'
import { Text } from './Text'

const TextBox = () => {
  const textStylePrimary = css`
    border: 1px solid blue;
  `

  const textStyleSecondary = css`
    border: 2px solid black;
  `

  return (
    <div>
      <Text cssStyle={textStylePrimary} />
      <Text cssStyle={textStyleSecondary} />
    </div>
  )

}

おわりに

最近依存しないようになコンポーネント設計を目指してたらちょっと気づいたことがあったので執筆しました。
ふと思ったことでもあるので、何かもっとこうした方がいいよ的な意見ありましたらばんばんコメントしてもらえますと幸いです

急ですがstylex楽しみですね

参考

emotion

10
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
3