[React]CSSの選択肢は何があるか？

# はじめに
ReactでのCSSを適用させる方法はいくつかあり、どれを使えば良いかという判断が難しい部分があります。そこで、それぞれどのような使い方をするか？を理解することで、自らのプロジェクトに合った手法をとるようにしましょう！

# クラス名の付与でのCSS適用
最も慣れ親しんだ、通常のCSSです。
しかし、Reactでは同じスタイルを再利用する場合は、`クラスではなくコンポーネントを利用するという考え方(コンポーネント駆動開発)なので、あまりオススメできるものではない`かもしれません。

```Button.css
.button {
  padding: 20px;
}
```

```Button.js
import './Button.css';

const Button = () => <button className="button" />;
```

## 特徴
- CSSやSASSなどが利用できる。
    - しかし、`すべてがグローバルで管理`されてしまうので保守・管理にコストがかかり、規模が大きくなるにつれ名前衝突の危険性が高まる。
- 主にルートファイル(App.js等)で、グローバルCSSを適用する時(リセットCSSやライブラリ使用時)に利用する。

# インラインスタイル
ReactにおけるJSXのstyle属性にオブジェクトを渡してスタイルを適用させる手法です。

```button.js
import React from "react";

const style = {
  minWidth: 64,
  lineHeight: 32,
  borderRadius: 4,
  border: "none",
  padding: 0 16,
  color: "#fff",
  background: "#639"
};

export default (props) => <button style={style} {...props} />;
```

## 特徴
- ドキュメントなどで例を示す場合や、動的に計算されるスタイルを追加する場合に利用する。
- styleにはスタイルしか渡すことが出来ないため、`:hover`などの擬似要素セレクタやメディアクエリを使うことは出来ません。
- しかし、[React公式](https://ja.reactjs.org/docs/dom-elements.html#style)にもあるように、再レンダリングの度に計算されるのでオススメできないです。

# CSS Modules
CSS Modulesとは、CSSを読み込んでコンポーネントごとにローカルスコープを作る方法のことです。

```Button.module.css
.error {
  color: white;
  background-color: red;
}
```

```Button.js
import styles from './Button.module.css'

const Button = () => (
  <button className={styles.error}>
    Destroy
  </button>
)
```

## 特徴
- コンポーネントレベルでスタイルを適用することができ、名前衝突を考慮する必要が無い。
- コード分割した上でminifyされた複数のcssファイルへとコンパイルされ、`描画のために読み込むCSSを最小限にしてくれるため、パフォーマンスは良い`です。
- 古い技術のため、今後は非推奨になっていく(であろう)

# CSS in JS
CSSをJSでする方法です。記述ファイルが一つで済むことが非常に楽で、propsで動的に一部のスタイルを変更することができます。
ここでは、有名なStyled Componentsを紹介しようと思います。

## Styled Components
StyledComponentsとは、タグ付きテンプレートリテラルを活用することでJavaScriptのオブジェクトではなく、CSS のシンタックスをそのまま使うことが出来るライブラリのことです。

```react
import styled from 'styled-components'

// aタグをButtonというコンポーネントとして生成する
const Button = styled.a`
  display: inline-block;
  border-radius: 3px;
  padding: 0.5rem 0;
  margin: 0.5rem 1rem;
  width: 11rem;
  background: transparent;
  color: white;
  border: 2px solid white;

  ${props => props.primary`
    background: white;
    color: black;
  `}
`

const Demo = () => (
  <div>
    <Button primary>
      Apply
    </Button>
  </div>
)
```

## 特徴
- テンプレートリテラル内でコンポーネントが受け取った Props を参照できるため、JSX をより簡潔に記述できる。
- スコープを作ることができる。
- タグとCSSの記述がセットになっていることに批判的な意見も多い。
    - 通常のpropsとスタイルとしてのpropsが混在してしまう。
    - ぱっと見で何のタグか判断が難しく、属性の設定のミスが起きる可能性がある。

# CSSフレームワーク(Tailwind CSS)
ユーティリティファーストのCSSフレームワークで、非常にReactとの相性が良いです。

```react
<figure class="md:flex bg-gray-100 rounded-xl p-8 md:p-0">
  <img class="w-32 h-32 md:w-48 md:h-auto md:rounded-none rounded-full mx-auto" src="/sarah-dayan.jpg" alt="" width="384" height="512">
  <div class="pt-6 md:p-8 text-center md:text-left space-y-4">
    <blockquote>
      <p class="text-lg font-semibold">
        “Tailwind CSS is the only framework that I've seen scale
        on large teams. It’s easy to customize, adapts to any design,
        and the build size is tiny.”
      </p>
    </blockquote>
    <figcaption class="font-medium">
      <div class="text-cyan-600">
        Sarah Dayan
      </div>
      <div class="text-gray-500">
        Staff Engineer, Algolia
      </div>
    </figcaption>
  </div>
</figure>
```

## 特徴
- classNameに適用したいクラスを追加していくだけですぐにスタイルが適用できる。
    - メディアクエリやhoverやfocusなどの状態も、prefixをつけるだけで簡単に指定できる。
- 具体的な数値を指定せずに定数を使用するため、スタイルに一貫性を保てる。
    - 具体的な数値も使えますし、テーマとしてカスタマイズも可能。

# UIライブラリ
Reactでスタイリングを考えると、`Material UI`などのUIライブラリの使用する場合もあるかと思います。UIライブラリには簡単にモーダルを実装できたりと便利な面がある分、学習に時間がかかるというデメリットもあります。
詳しい情報はここでは割愛させていただきますが、以下のようなUIライブラリがよく使われているようなので、気になった方は調べてみてください！

- [Material-UI](https://material-ui.com/)

- [Ant Design](https://ant.design/)

- [Mantine](https://mantine.dev/)

# 終わりに
どれを使うか、どれを組み合わせて使うかなどはプロジェクトごとに変化するので柔軟に対応していきましょう。それぞれの得意不得意を理解することで導入すべきか判断できると思うので、ぜひ参考にしてください！

# 参考
[【React】CSS ModulesでCSSとSass(SCSS)のローカルスコープを作る]
(https://www.i-ryo.com/entry/2020/12/11/065700)

[Reactのコンポーネントのスタイリングをどうやるか]
(https://qiita.com/lightnet328/items/218eb1c4a347302cc340)

[Reactにおけるスタイリング手法まとめ]
(https://zenn.dev/chiji/articles/b0669fc3094ce3)

[ReactのCSSの選択肢を比較してみた]
(https://zenn.dev/irico/articles/d0b2d8160d8e63)

[Tailwind CSS]
(https://tailwindcss.com/)