スタイルの適用方法で混乱したのでMUIとChakra UIを例にまとめてみた

## これはなに？
こんにちは、最近リモートで体重が急増したので焦ってランニングをしている[@mu-suke08](https://twitter.com/chelsea08ym)です。

流行り廃りが激しいフロントエンド業界では、常に新しいUIフレームワークが生まれ、使われなくなるというのが当たり前のように起きています。
筆者はその流れに揉まれて、「結局どの書き方が良いのさ」という思考に陥ったためこれを機にまとめてみようと思います。

今回はMaterial UI(現在のMUI)とChakra UIを使ってみてそれぞれのCSSのあて方についてみていこうと思います。

:::note warn
注意
この記事ではMUIのv4以前をMaterial UI、v5以降をMUIと呼びます。
:::


紹介する内容は以下
- Material UI
- MUI
- Chakra UI



## Material UI
Material　UIのv4以前はMaterial　UI, v5以降はMUIとなっています。
知っている人も多いと思いますが、v5では破壊的な変更があり、styling solutionも姿をガラリと変えています。

ここでは変更以前(v4まで)のstyling solutionを3つを紹介します。

### Hook API
Hook APIはmakeStyleを使った書き方になります。
筆者自身もMaterial UIを使っていた頃によく書いていて、いくつか記事を見ましたがにこれが主流なのかなと思っています。
スネークケースからキャメルケースに変わったくらいで従来のcssと書き方はほぼ一緒です。
クラス名でスタイリングをしている辺りが従来のcssの書き方に似ていますね。

```tsx
import * as React from 'react';
import { makeStyles } from '@mui/styles';
import Button from '@mui/material/Button';

const useStyles = makeStyles({
  root: {
    background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
    border: 0,
    borderRadius: 3,
    boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
    color: 'white',
    height: 48,
    padding: '0 30px',
  },
});

export default function Hook() {
  const classes = useStyles();
  return <Button className={classes.root}>Styled with Hook API</Button>;
}

<Button className={classes.root}>Styled with Hook API</Button>
```

### Styled components API
Styled components APIは名前の通りstyled-componentsに則って、既存のcomponentをラップして、任意のコンポーネントに再定義するという方法です。
汎用性の低いコンポーネントを書くときは少し面倒だなという印象です。

```tsx
import * as React from 'react';
import { styled } from '@mui/styles';
import Button from '@mui/material/Button';

const MyButton = styled(Button)({
  background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
  border: 0,
  borderRadius: 3,
  boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
  color: 'white',
  height: 48,
  padding: '0 30px',
});

export default function StyledComponents() {
  return <MyButton>Styled with styled-components API</MyButton>;
}

<MyButton>Styled with styled-components API</MyButton>
```

### Higher-order component API
これは筆者自身も馴染みがないのですが、
**スタイルとUIの2つを用意してexportする際に2つを合体させる**というものです。
`styled-components`と若干書き方が似ていますがなんというか、書きづらい印象です。。

```tsx
import * as React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@mui/styles';
import Button from '@mui/material/Button';

const styles = {
  root: {
    background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
    border: 0,
    borderRadius: 3,
    boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
    color: 'white',
    height: 48,
    padding: '0 30px',
  },
};

function UnstyledComponent(props) {
  const { classes } = props;
  return <Button className={classes.root}>Styled with HOC API</Button>;
}

UnstyledComponent.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(UnstyledComponent);
```

## MUI
https://mui.com/

ここでは変更後(v5以降)のsolutionについて言及していきます。

>MUI's styling solution is inspired by many other styling libraries such as styled-components and emotion.
出典： [Why use MUI's styling solution?](https://mui.com/styles/basics/#why-use-muis-styling-solution)

ここにも書いてあるとおりstyled-componentsとemotionの影響を受けていて、以下のような書き方になりました。

```tsx
import Button from "@mui/material/Button"

import React from "react"

const MyButton: React.VFC = () => {
  return (
    <Button
      sx={{
        background: "linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)",
        border: "0",
        borderRadius: "3px",
        boxShadow: "0 3px 5px 2px rgba(255, 105, 135, .3)",
        color: "white",
        height: "48px",
        padding: "0 30px",
      }}
    >
      Styled with MUI
    </Button>
  )
}

export default MyButton
```


## Chakra UI
https://chakra-ui.com/

Chakra UIは前述したMUIの書き方と似ている印象です。

```tsx
import { Button } from "@chakra-ui/react"
import React from "react"

const MyButton: React.VFC = () => {
  return (
    <Button
      background="linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)"
      border="0"
      borderRadius="3px"
      boxShadow="0 3px 5px 2px rgba(255, 105, 135, .3)"
      color="white"
      height="48px"
      padding="0 30px"
    >
      Styled with Chakra UI
    </Button>
  )
}

export default MyButton
```



## まとめ
Material UI(v4)からChakra UIに乗り換えたときにChakra UIのスタイルのあて方に感動しました。
というのも、**CSSを書くというよりかは、Flutterのようなスタイルとそれを適用するコンポーネントが同じ位置にあることがすごい直感的でわかりやすい**なと思ったからです。

バージョンアップしたMUIを改めてみてみると、Chakara UIと同じ書き方をしていたので、今のスタイルの適用方法はこれなんだなというのを理解しました。

冒頭でも述べたようにここら辺は流行り廃りが激しいところなので適宜キャッチアップしていきたいです。

ではまた！


## 参考サイト
https://mui.com/styles/basics/#why-use-muis-styling-solution

https://mui.com/system/basics/

https://chakra-ui.com/docs/comparison

https://styled-system.com/

https://zenn.dev/terrierscript/books/2021-05-chakra-ui/viewer/1-1-2-box