運用中のアプリケーションにReact Hooksを入れてみて気付いたこと

[前回の記事](http://google.com)では、「運用中アプリケーションのReactのバージョンを試しに最新にした時の、npmライブラリ変更とその解決法メモ」を投稿しました。折角Reactのバージョンを最新にしたので、React Hooksを導入してみました！
React Hooksについては初心者なので悪しからず…👀

##導入

###`useState`
functionコンポーネントがローカルステートを使えるようになりました。ローカルステートの初期値の設定や、setState等が出来ます。
まず、今までReactをimportしていたところを、下のように`useState`を使えるようにしてあげます。

```javascript
import React, { useState } from 'react'
```

まずはclassで作っていたコンポーネントをFCに変えちゃいます。

以前までのコード

```javascript
class Component extends React.Component {
  ...
}
```

変更後のコード

```javascript
const Component = () => {
  ...
}
```

ローカルステートは下のように記述していたのを、`useState`を使って変更しました。

```javascript
/* 変更前 */
state = {
  UserSelf: {}
}

/* 変更後 */
const [UserSelf, setUserSelf] = useState({})
```

`UserSelf`がステート名、`setUserSelf`は`setState`みたいなもので、`UserSelf`を変更したい場合に用います。
useStateの引数の中には、初期値を入れてあげます。これで準備は完了です！

今まで`this.state.UserSelf`、`this.setState({ UserSelf: { id: 1 } })`とか書いていたところを、下のように書き替えてあげます。

```javascript
return (
  <div>
    /* 以前までのコード */
    {this.state.UserSelf}
    /* 変更後 */
    {UserSelf}
  </div>
)
```

```javascript
/* 以前までのコード */
this.setState({ UserSelf: { id: 1 } })
/* 変更後 */
setUserSelf({ id: 1 })
```

##`useEffect`
`componentDidMount()`などライフサイクルメソッドを使用しているので、こちらも新しい`useEffect`に書き換えていきます！
`useEffect`はライフサイクルメソッドに代わるものです。`componentDidMount()`、`componentDidUpdate()`、`componentWillUnmount()`を組み合わせたものというイメージです。

前準備として、`useEffect`を使えるようにしておきます。

```javascript
import React, { useState, useEffect } from 'react'
```

`componentDidMount()`内の記述を一旦関数に書き換えてuseEffect内で呼び出す事にしました。

以前までのコード

```javascript
class Component extends React.Component {
  ...
  async componentDidMount() {
    const response = await axios.get(`https://samplejson.com/${this.props.resource}`)
    this.setState({ resource: response.data })
  }
  ...
}
```

↓
変更後のコード
`fetchResource()`という名前の関数で作成しました。

```javascript
const Component = (props) => {
  ...
  const fetchResource = async () => {
    const response = await axios.get(`https://samplejson.com/${props.resource}`)
    this.setState({ resource: response.data })
  }
  ...
}
```

`fetchResource()`を`useEffect`の中で呼び出してみます！

```javascript
const Component = props => {
  ...
  const fetchUser = async props => {
    setUser(foo)
    setLoading(false)
  }

  useEffect(() => {
    fetchUser(props)
  }, [props])
  ...
}
```

こちらの記述では上手くいきませんでした。
（動画の英語が分からなかった訳ですが笑、）上手くいかなかったのは、`useEffect`の非同期処理が何度も繰り返し呼ばれているようです。
これには`useEffect`の第二引数が関係してくるようです。こちらの記事を参考に勉強させていただきました！
[useEffectフックのしくみ](https://qiita.com/ossan-engineer/items/740425a0df937a47e093)

###第二引数を指定しない場合
ノンストップでAPIが呼び出され、毎度リレンダーされる。

```javascript
useEffect(() => {})
```

###第二引数に空の配列を指定した場合
初期レンダリングだけ実行される。（`componentDidMount()`）

```javascript
useEffect(() => {},[])
```
参考にさせて頂いた記事では、「空配列を渡すとバグの原因になる。依存関係が不足していると`useEffect`が更新された時予期せぬ挙動の原因となるでしょう」とありました。注意が必要そうです…！


###第二引数に値を指定した場合
引数に渡した値が更新されるたびに、`useEffect()`が呼ばれその度にレンダーしてくれる。

```javascript
useEffect(() => {},[value])
```

なるほどと動画を見ながら第二引数にローカルステートを色々入れて試したのですが、何度もレンダーされまくってしまいました…！😭 解決法は上記で紹介させ頂いた[useEffectフックのしくみ](https://qiita.com/ossan-engineer/items/740425a0df937a47e093)の「useEffectでデータを取得する」の章がすっごく分かり易かったです！こちらを参考に修正しました。

```javascript
useEffect(() => {
  fetchUser(props)
}, [setUser])
```

今回は、第引数に __セッター関数__ を渡してあげるのが正解のようでした…！（ずっとステート名入れてた〜😭💦）
これで何度もレンダーされるのは解消されました。🎉


## 関数を使い回せるように
`const [UserSelf, setUserSelf] = useState({})`と`useEffect(() => {})`をまとめて、別ファイルにすれば、使い回しが出来ます！👀 
Udemyでは、別ファイルの関数を`useResources()`とし、非同期のエンドポイントを引数に渡してあげるようにすればどのコンポーネントでも使えると紹介していました。

```javascript
// ユーザー一覧コンポーネント
import useResources from './useResources';

const UserList = () => {
  const users = useResources('users')

  return (
    ...
  )
}

// 記事一覧コンポーネント
import useResources from './useResources';

const ResourceList = () => {
  const users = useResources('resource')

  return (
    ...
  )
}
```


##終わりに
16.6で追加された`lazy`&`Suspense`も試したい…！
[React 16.6で追加されたReact.Suspenseについて](https://qiita.com/yoshi_ksk/items/706acf084a7f2c560b26)
（超便利っ！！）バージョンアップと共に便利になっていくReactに感動しているのと同時に、英語に怖じ気ずかないようにしようと思いました〜

また、今回もUdemyを参考に勉強しました。[Modern React with Redux -2019 Update](https://www.udemy.com/react-redux/)
（恥ずかしい話、英語が聞き取れず第二引数のくだりがほとんど分かりませんでした😭ですが日本語記事でも理解を深めることが出来ましたので、大助かりでございました…っ！）

React公式ドキュメントでも「[フックの導入](https://ja.reactjs.org/docs/hooks-intro.html)」が公開されていました。React界隈の著名人もReact Hooksについてブログ記事で使い方のレクチャーをしています！

また…、
この記事もあっさり＆ざっくり、パラパラしすぎていると自負しているので笑、文章の書き方についても勉強します😅