Reactの思想を理解してリファクタする

## 抱えていた疑問
propsの理解やcomponentの作り方、hooks、ES2015以降のjsの書き方はわかる。
でも、`React的に最適なリファクタは何？`ということが疑問でした。
Reactをより理解し、疑問を解消できればと思います。

## Reactは宣言的である。

答えを求めてReactのTOPページへやってきました。
そこには`宣言的`という言葉が目立つところに存在します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206790/a7e7d8c8-b896-c8ac-c335-0ed828616298.png" width="400">
<br><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206790/b3335e9b-de29-a243-4ac0-ef4da978fd16.png" width="200">

> Declarative views make your code more predictable and easier to debug.

`宣言型ビューは、コードをより予測しやすくし、デバッグを容易にします。`
命令的ではなく、宣言的にコードを書いていくことを思想としているようです。

## 宣言的?命令的?それは何？

### 命令的とは何か

何をするか？を1つ１つ記述(命令)していくこと。

```js
/*
bodyを取ってくる
h1を生成する
h1に"hello"と入れる
bodyにh1を入れる
*/
const body = document.body;
const h1 = document.createElement('h1');
h1.innerText = 'ようこそ!';
body.appendChild(h1);
```

##### 特徴

- カスタム性が高い
- コードが多くて実装が大変
- 見通しが良くない
- 変更も大変

### 宣言的とは何か

欲しい結果だけを要求する。

```html
 <body>
   <h1>ようこそ!</h1>
 </body>
```

##### 特徴

- 細かいやり方は(コンピューターやライブラリに)任せる
- 実装がシンプル
- 変更も容易

[宣言的、命令的の例:コーヒーの淹れ方](https://zenn.dev/masahiro_toba/books/a808e953a39110/viewer/0383a4)

## より宣言的に進化するReact

#### クラスコンポーネントから関数コンポーネントへ

クラスコンポーネントとは、`propsを用いて自身の描画内容を決定するという`仕組みがあるだけでも、最低限の宣言的UIであるといえます。
しかし、[hook(フック)](https://ja.reactjs.org/docs/hooks-intro.html)の登場により、より宣言度合いを高めました。

一昔前のクラスコンポーネントです。
「component作成時に状態(この場合count)を0に初期化しなさい」という命令的なコードを含んでいます。

```jsx
class Counter extends React.Component {
   constructor(props) {
      super(props);
      this.state = {count:0}
   }
   render() {
     return {
        <button onClick={() => this.setState(state => ({ count: state.count +1 }))}>
          {count}
        </button>
      }
   }
}
```

次は関数コンポーネントの例です
React16.8から使えるようになった`hook(フック)`の機能である`useState`を呼び出し、状態を初期化します。
このAPIを呼びだせば、あとはReactが`よしなにやってくれる`という点で、宣言的度合いが増しています。
(記述もスリムになりましたネ)

```jsx
import { useState } from 'react'

const Counter = () => {
  const [count, setCount] = useState(0);
  return (
    <button onClick={()=> setCount(c => c + 1)}>
      {count}
    </button>
  )
}
```

`(ボタンを)クリックしたらcountを1つ増やしなさい` という命令をHTML部分に含んでしまいました。
より宣言的にするため、関数は外へ出すリファクタを行う方が良さそうです。

```diff_apache

+ const addCount = () => {
+   setCount(c => c + 1)
+ }

- <button onClick={()=> setCount(c => c + 1)}>
+ <button onClick={addCount}>
```


## React18の新機能も宣言的

#### Suspense(待機処理)の登場

React18で導入されたSuspenseは、従来命令的だった待機処理を`宣言的`に書くことができます。

```jsx
//今までの待機処理
const App = () => {
  return <MyComponent />
}
const MyComponent = () => {
  // APIから情報を取得(SWRライブラリを使用)
  const { loading , data } = useSWR(URL, getData)

  if (loading) {
    return <Loading />
  }
  return <p>私の名前は{data.name}です</p>
}
```
今までは`if (loading)`を使用し、待機中のコンポーネントを出し分けていました。
React18では `if (loading)` 部分をSuspenseが`よしなに`行ってくれることで、より宣言的になりました。

```jsx
//Suspense使用
const App = () => {
  return (
    <Suspense fallback={<Loading />}>
      <MyComponent />
    </Suspense>
  )
}
const MyComponent = () => {
  const { data } = useSWR(URL, getData)
  return <p>私の名前は{data.name}です</p>
}
``` 

## Reactの思想を理解してリファクタする
   
Reactの進化、新機能からも見て取れるよう、`宣言的`であることはブレていません。
そんなReactに対し、`命令的 、場当たり的な実装をする`ということはReactの思想に反するように思えます。
(useRefで初期化したものをuseEffect内で判定処理に使うなど)
今は問題なく動くかもしれませんが、今後のバージョンアップ(破壊的変更)に耐えることができない,,,こともありえます。
その時、バージョンアップのために多くの改修が予想されます。

`Reactは宣言的である`という思想を理解した上で実装、リファクタを行うことが大切だとわかりました。

---

自分の考えが絶対正しいとは思っていません！！
ぜひぜひコメントをお願いします!!