【コード品質】綺麗なReactコード 中級 7例

# 初めに
- Reactでは，多くのデータを保持，変更し，動的なコンポーネントを表現している
- データの受取，代入，保持はReact独特な手法によって行われている

#### 前提
基本: 数行レベルで綺麗なコードが書けること

https://qiita.com/JNJDUNK/items/e040925e546a45a1d913

## 1. 値の受け渡しは簡潔であるか
#### 1-1. 受取：値をまとめて受け取る
```jsx
const userInfo = {
  username: 'Jnjdunk',
  address: 'Tokyo',
  favorite: 'Travel',
};

// NG
const username = userInfo.username;
const address = userInfo.address;
const favorite = userInfo.favorite;

// 🥴 Good
const { username, address, favorite } = userInfo;
```

#### 1-2. 代入：プロパティ値の省略形を使えているか
```jsx
// NG
const profile = {
  username: username,
  address: address,
  favorite: favorite,
  age: 88,
};

// 🥴 Good
// 変数のみを最初に記述，値をもつのは下に記述
const profile = {
  username,
  address,
  favorite,
  age: 88,
};

// 😎 Best
const age = 88;
const profile = {
  ...userInfo,
  age,
};
```


## 2. 関数コンポーネントの方が可読性は高い

❗️あくまで綺麗さの観点

```jsx
// NG　クラスコンポーネント
class UserArea extends React.Component {
  render() {
    return <h1>Hello, {this.props.username}</h1>;
  }
}

// 🥴 Good　関数コンポーネント
const UserArea = (props) => {
  return <h1>Hello, {props.username}</h1>;
};
```
参照：[Reactドキュメント](https://ja.reactjs.org/docs/components-and-props.html)

## 3. useEffectは複数書いても良い
無理に一つの`useEffect`の中に書く必要はない

```jsx
// NG
useEffect(() => {
  const getApi1 = async () => {
    const response = await api('classinfo');
    命令1(response);
  };

  const getApi2 = async () => {
    const response = await api('userinfo');
    命令2(response);
    命令3(response);
  };
  getApi1();
  getApi2();
}, []);

// 🥴 Good
// 1つ目
useEffect(() => {
  const getApi = async () => {
    const response = await api('classinfo');
    命令1(response);
  };
  getApi();
}, []);

// 2つ目
useEffect(() => {
  const getApi = async () => {
    const response = await api('userinfo');
    命令2(response);
    命令3(response);
  };
  getApi();
}, []);
```

## 4. 少ないuseStateでデータを流す
```jsx
// NG
// 記述ミスが起こりやすくなる
const [userId, setUserId] = useState();
const [userName, setUserName] = useState();
const [userAddress, setUserAddress] = useState();
const [userFavorite, setUserFavorite] = useState();

setUserId(props.userInfo.userid);
setUserName(props.userInfo.username);
setUserAddress(props.userInfo.address);
setUserFavorite(props.userInfo.favorite);

// 🥴 Good
const [userInfo, setUserInfo] = useState();
setUserInfo(props.userInfo);
```
```jsx
// 😎 特定のキーに値を代入したいとき
const favorite = 'Eating';
setUserInfo((prevUserInfo) => ({ ...prevUserInfo, favorite }))
```

## 5. 使用するPropsの値の見える化
```jsx
const userProfile = (props) => (
  <Box>
    {props.username}
    <span>{props.address}</span>
  </Box>
);

// 🥴 Good
const userProfile = ({ address, username }) => (
  <Box>
    {username}
    <span>{address}</span>
  </Box>
);
```

## 6. データ保持系はルール通りに使えているか
useContext, props, reduxそれぞれ単体だけでもアプリは実現できる．
それぞれの特性を理解して使うこと．
#### ルール例
1. `useContext`は浅く広い階層のコンポーネントに適応
     - a) デフォルトStyle
     - b) Header, Footer
     - c) 何かの状態，on/off
1. 独立させたいコンポーネントには，`props`を使用し，`useContext`を利用しないこと
     - a) 依存関係が親の値のみになる
     - b) 切り離し，他での利用が簡単になる
1. 複雑なデータ変更パターンが多いとき, Reduxを使用する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557072/98729d3e-3bf9-e816-7ac9-680be1098b65.png" width=800>

## 7. Style方法 の使い分けはできているか
- 一つの記法で複雑なスタイリングを行うことは難しい
- Styleの使用ルールは明記されるべき

#### 一例
#### 7-1. CSS Module：基本はCSS/SCSSベースでデザインする
```css
/* style.css */
.save_button {
  color: white;
  background: black;
}
```

```jsx
// 書き方1
import styles from './style.css';
const buttonArea = () => {
  return <Button style={style.save_button}>{text}</Button>;
};

// 書き方2
const buttonCn = "save_button";
const buttonArea = () => {
  return <Button className={buttonCn}>{text}</Button>;
};
```

#### 7-2. Inline CSS: 一部の動的な変更
```jsx
const textStyle = {
  display: isAdmin ? 'none' : 'block',
};
const textArea = () => {
  return <div style={textStyle}>{text}</div>;
};
```

#### 7-3. CSS In Js　変更できないクラス名のスタイルを動的に変更したいとき
外部コンポーネントなど，力ずく...

```jsx
  return (
    <>
      <style>
        {`
        .text {
            color: ${props.color};
            background: black;
        }
        `}
      </style>
      <div className='text'>{text}</div>
    </>
  );
```

## 応用編
https://qiita.com/JNJDUNK/items/4ac302482be451153bd9

# 最後に
**良いコードは，コードの書き方だけではない**．
様々な記法がある中で，プロジェクト内でStyle，データに関する**ルールが統一されていること**はコードを理解する上で重要である．
**良いコードの答えはない**．
コードの綺麗さは「芸術的な観点」に近く，一つの正解があるわけではない．[MaterialUI](https://mui.com/getting-started/usage/)，[Next](https://nextjs.org/docs/basic-features/layouts)の公式ドキュメントで表現されている記法が正解ではなく，少なくとも，プロダクトに適した方法で保守性，移植性を考慮して追求することで，正解に近づけると考えている．