🔥

【React】styled-componentsでpropsを使う時の書き方

2022/08/25に公開

Reactとtypescriptを使ってstyled-componetsで、styleを調整する際にpropsを使い動的にスタイルを変える方法をメモします。
公式のサイト通りやってもエラーが出てしまった人向けです。

公式サイト
https://styled-components.com/

まずは公式通りの書き方

import styled, { css } from 'styled-components'

const Button = styled.button`
  background: transparent;
  border-radius: 3px;
  border: 2px solid palevioletred;
  color: palevioletred;
  margin: 0 1em;
  padding: 0.25em 1em;

  ${props =>
    props.primary &&
    css`
      background: palevioletred;
      color: white;
    `};
`

render(
  <Container>
    <Button>Normal Button</Button>
    <Button primary>Primary Button</Button>
  </Container>
);

最後のステップとして紹介されています。
{ css } を styled-components から import してね、と書いてます。
そして、${} の中に props を受け取った後の処理を書いていきます。

この例だと、props に primary があれば背景と文字色を変えるという処理です。

typescriptだとエラーになります。

Property 'primary' does not exist on type 'ThemedStyledProps<Pick<DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "key" | keyof ButtonHTMLAttributes<...>> & { ...; }, any>'.

TypeScriptでの書き方

import styled, { css } from 'styled-components'

const Button = styled.button < { primary: any }>`
  background: transparent;
  border-radius: 3px;
  border: 2px solid palevioletred;
  color: palevioletred;
  margin: 0 1em;
  padding: 0.25em 1em;

  ${props =>
    props.primary &&
    css`
      background: palevioletred;
      color: white;
    `}
`;

分割代入

import styled, { css } from 'styled-components'

const Button = styled.button < { primary: string }>`
  background: ${({ primary }) => (primary ? 'palevioletred' : 'transparent')};
  border-radius: 3px;
  border: 2px solid palevioletred;
  color: ${({ primary }) => (primary ? 'white' : '#333')};
  margin: 0 1em;
  padding: 0.25em 1em;
`

コンポーネントとして使う場合

import React from 'react'
import styled, { css } from 'styled-components'

type Props = {
  children: string,
  color: boolean,
  primary: any
}

const Btn = (props: Props) => {
  const { children, color, primary } = props;
  return (
    <SBtn primary={primary}>{children}</SBtn>
  )
}

export default Btn

const SBtn = styled.button < { primary: any }> `
  width: 100px;
  height: 60px;
  display: grid;
  place-items: center;
  background-color: ${({ primary }) => (primary ? 'palevioletred' : 'transparent')};
  font-size: 16px;
  font-weight: bold;
  letter-spacing: 0.2em;
  border-radius:5px;
  color: white;
`;

Discussion