🔥
【React】styled-componentsでpropsを使う時の書き方
Reactとtypescriptを使ってstyled-componetsで、styleを調整する際にpropsを使い動的にスタイルを変える方法をメモします。
公式のサイト通りやってもエラーが出てしまった人向けです。
公式サイト
まずは公式通りの書き方
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``}
`;
分割代入
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