styled-componentsを使ったReactコンポーネント作成入門
styled-componentsを使ったReactコンポーネント作成入門:
「ランサーズ Advent Calendar 2018」9日目の記事になります。
昨日は、「ランサーズでインターンをして感じたプログラミング学習における個人とチームの違い」でした。
ランサーズはいくつかReactのプロダクトがあるのですが、スタイルはcss-modulesを使用して書いていました。
最近Reactの開発にstyled-componentsを採用したところ、非常に書き心地が良かったので紹介します。
styled-copmonentsはJavaScriptのファイルの中でcssを定義するためのライブラリで、いわゆるCSS in JSの一種です。
styled-componentsはstyled.[タグ名]`[css]`でスタイルをあてたコンポーネントを作成することができます。
作成したコンポーネントは変数名をタグ名にして使うことができます。
ちなみにstyled.h1にテンプレートリテラル(``)が続いている構文が見慣れないかもしれないですが、これはタグ付きテンプレートリテラルと呼ばれる構文です。
styled-componentsを使って下の画像のようなボタンのコンポーネントを作ってみます。
このボタンはdefault・Primary・Dangerの三種類の色があります。
また大きさが2種類、disabledとそうではないパターンが存在します。
最終的なコードはこちらに置いてあります。
はじめにdefaultのボタンを作り、すべてのパターンに共通する箇所のスタイルをあてます。
ここでは、フォントのサイズや丸みをつけたり、ホバー時のカーソルがポインターになるようにしています。
次に色を変えてみます。
今回はdefaultとPrimary、Dangerの3タイプのボタンが使えるようにします。
ここではdefaultのbuttonにbackgroudやcolorを追加して新しいコンポーネント
defaultのサイズに加えて、大きいサイズのボタンが使えるようにします。
コンポーネントのpropsにlargeを与えることでサイズを変更できるようにします。
cssはテンプレートリテラルを使って記述するので
またstyled-componentsで
上のコードではpropsにlargeが与えられた場合とそうでない場合で、paddingを変えています。
ボタンがdisabledのときに色とカーソルの形状を変えます。
大きさを変えるときと同様にpropsにdisabledが与えられたときにスタイルを変えます。
css``はcssを変数化して、そのcssをテンプレートリテラル内に挿入したい場合に使います。
ここではdisabledの場合のスタイルを変数化して、propsのdisabedが存在した場合に挿入しています。
これで完成です。
同じものをcss-modulesで作ろうとすると下のようになると思います。
比較をするとstyled-componentsには以下のような利点があると考えます。
styled-componentsを使ってボタンのコンポーネントを作成しました。
css-modulesと比較をすると簡潔なコードでコンポーネント作成ができていることがわかると思います。
以上、「ランサーズ Advent Calendar 2018」9日目の記事でした。
明日は「ランサーズエンジニアのキーボードの世界」です。お楽しみに!
「ランサーズ Advent Calendar 2018」9日目の記事になります。
昨日は、「ランサーズでインターンをして感じたプログラミング学習における個人とチームの違い」でした。
ランサーズはいくつかReactのプロダクトがあるのですが、スタイルはcss-modulesを使用して書いていました。
最近Reactの開発にstyled-componentsを採用したところ、非常に書き心地が良かったので紹介します。
styled-componentsとは
styled-copmonentsはJavaScriptのファイルの中でcssを定義するためのライブラリで、いわゆるCSS in JSの一種です。styled-componentsはstyled.[タグ名]`[css]`でスタイルをあてたコンポーネントを作成することができます。
作成したコンポーネントは変数名をタグ名にして使うことができます。
App.jsx
import styled from "styled-components"; const Title = styled.h1` font-size: 30px; color: red; `; const App = () => ( <Title>タイトル</Title> )
コンポーネントを作ってみる
styled-componentsを使って下の画像のようなボタンのコンポーネントを作ってみます。このボタンはdefault・Primary・Dangerの三種類の色があります。
また大きさが2種類、disabledとそうではないパターンが存在します。
最終的なコードはこちらに置いてあります。
共通部分をつくる
はじめにdefaultのボタンを作り、すべてのパターンに共通する箇所のスタイルをあてます。ここでは、フォントのサイズや丸みをつけたり、ホバー時のカーソルがポインターになるようにしています。
共通部分をつくる
const Button = styled.button` font-size: 1rem; padding: 5px 10px; border-radius: 5px; cursor: pointer; `; const App = () => ( <div> <Button>Button</Button> </div> )
色を変える
次に色を変えてみます。今回はdefaultとPrimary、Dangerの3タイプのボタンが使えるようにします。
色を変える
const Button = styled.button`...`; const PrimaryButton = styled(Button)` border: none; color: white; background: #007bff; `; const DangerButton = styled(Button)` border: none; color: white; background: #dc3545; `; const App = () => ( <div> <Button>Button</Button> <PrimaryButton>Primary</PrimaryButton> <DangerButton>Danger</DangerButton> </div> )
styled([コンポーネント名])
で既存のコンポーネントに対してstyleを追加することができます。ここではdefaultのbuttonにbackgroudやcolorを追加して新しいコンポーネント
PrimaryButton
,DangerButton
を作っています。
大きさを変える
defaultのサイズに加えて、大きいサイズのボタンが使えるようにします。コンポーネントのpropsにlargeを与えることでサイズを変更できるようにします。
大きさを変える
const Button = styled.button` font-size: 1rem; padding: ${props => (props.large ? "10px 15px" : "5px 10px")}; border-radius: 5px; cursor: pointer; `; const PrimaryButton = styled(Button)`..`; const DangerButton = styled(Button)`...`; const App = () => ( <div> <div> ... </div> <div> <Button large>Button</Button> <PrimaryButton large>Primary</PrimaryButton> <DangerButton large>Danger</DangerButton> </div> </div> )
${}
の中に変数などを入れることができます。またstyled-componentsで
${}
の中に関数を与えることもでき、第一引数はコンポーネントのpropsになります。上のコードではpropsにlargeが与えられた場合とそうでない場合で、paddingを変えています。
disabledのときにスタイルを変える
ボタンがdisabledのときに色とカーソルの形状を変えます。大きさを変えるときと同様にpropsにdisabledが与えられたときにスタイルを変えます。
disabledのときにスタイルを変える
import styled, { css } from 'styled-components'; const Button = styled.button` ... ${props => props.disabled && disabledCss} `; const disabledCss = css` opacity: 0.5; cursor: default; `; const PrimaryButton = styled(Button)`..`; const DangerButton = styled(Button)`...`; const App = () => ( <div> ... <div> <div> <Button disabled>Button</Button> ... </div> <div> <Button large disabled>Button</Button> ... </div> </div> </div> )
ここではdisabledの場合のスタイルを変数化して、propsのdisabedが存在した場合に挿入しています。
これで完成です。
css-modulesとの比較
同じものをcss-modulesで作ろうとすると下のようになると思います。css-modulesの場合
import React from 'react'; import styles from './styles.css'; function createButton(type) { return ({children, large, disabled}) => { const classNameList = [styles.button, styles[type]] if (large) { classNameList.push(styles.large) } if (disabled) { classNameList.push(styles.disabled) } return ( <button className={[styles.button]}>{children}</button> ) } } const Button = createButton('default'); const PrimaryButton = createButton('primary'); const DangerButton = createButton('danger');
- styled-componentsの中だけで完結する。簡単なコンポーネントであればreactをimportする必要すらない。
- css-modulesでスタイルを変えることは最終的にclassNameに与える文字列をどうやって生成するかに帰着する。そのためこのような簡単なコンポーネントでも複雑なロジックが発生する。styled-componentでは複雑化しない。
- 一つのファイルで完結するので見通しが良い。
まとめ
styled-componentsを使ってボタンのコンポーネントを作成しました。css-modulesと比較をすると簡潔なコードでコンポーネント作成ができていることがわかると思います。
以上、「ランサーズ Advent Calendar 2018」9日目の記事でした。
明日は「ランサーズエンジニアのキーボードの世界」です。お楽しみに!
コメント
コメントを投稿