React HooksのuseStateで関数コンポーネントに状態を持たせよう

#目次

- [概要](#概要)
- [React Hooksとは](#react-hooksとは)
- [Hooks Systemの紹介](#hooks-systemの紹介)
- [useStateの使い方](#usestateの使い方)
- [まとめ](#まとめ)

#概要
この記事では、React 16.8で導入された**Hooks**についての説明と、その中でもclassコンポーネントのようにstateを管理する機能である**useState**の使い方についてまとめています。なおその他**useEffect**などのAPIについては今後別の記事に投稿したいと思っています。
私のように現在Reactについて学習中の方の一助となれば幸いです。

###前提条件

- Reactについて基本的な部分を理解している
  - Reactの基本については[別の記事](https://qiita.com/jima-r20/items/48220ec1980535280a66)にもまとめていますので、是非参考にしてみてください

###環境

| 導入    |  version |
|:-------|---------:|
| react  | 16.13.1  |

#React Hooksとは
Reactでコンポーネントを作成する際には、クラスコンポーネントと関数コンポーネントの２種類を作成することが可能です。しかし、コンポーネントで**状態(State)を持たせて操作したり、ライフサイクルメソッドなどを記述できるのはクラスコンポーネントのみで、関数コンポーネントは基本的にJSXを返すだけでした**。

そこで導入されたのが**Hooks**です。Hooksを用いることで、関数コンポーネントでもStateやライフサイクルメソッドを扱えるようになります。

![hooks.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622836/36154881-60e1-bc17-58dd-df30dc636e7d.png)

またHooksの利点として、[React公式](https://ja.reactjs.org/docs/hooks-intro.html)には以下のことが書かれています。
> フックを使えば、ステートを持ったロジックをコンポーネントから抽出して、単独でテストしたり、また再利用したりすることができます。フックを使えば、ステートを持ったロジックを、コンポーネントの階層構造を変えることなしに再利用できるのです。このため、多数のコンポーネント間で、あるいはコミュニティ全体で、フックを共有することが簡単になります。

要約すると、Hooksを用いた方がテストやロジックの共有を簡単にできるということです。

また個人的な話ではありますが、Reactアプリケーションを作成しているときコンポーネントによってクラスコンポーネントであったり、関数コンポーネントであったりと記述方法がバラバラな場合が多くありました。
しかしHooksを利用して全てのコンポーネントを関数コンポーネントとして記述してあげることで、コードの可読性を向上させることもできるようになったと感じています。

#Hooks Systemの紹介
では次にHooksにはどのような機能があるのかを見てみましょう。ここでは簡単な紹介になりますので、詳細に知りたい方は[公式のAPIリファレンス](https://ja.reactjs.org/docs/hooks-reference.html)を見ていただければと思います。

| API             | 使用目的                                |
|:----------------|:---------------------------------------|
| **useState**    | コンポーネントレベルのStateを使用できるようにする  |
| **useEffect**   | Lifecycleメソッドを使用できるようにする         |
| **useContext**  | Contextシステムを使用できるようにする          |
| useRef          | Refシステムを使用できるようにする              |
| useReducer      | Reducerを介してデータを記述できるようにする     |

上記表で紹介したもの以外にもいくつか種類がありますので、必要に応じて学んでいくと良いかと思います。

#useStateの使い方
useStateを記述する際に必要なのは以下の構文です。

```react
const [currentValue, setCurrentValue] = useState(initialValue);
```
ここで使用している`currentValue`, `setCurrentValue`, `initialValue`は任意の名前で大丈夫です。
それぞれが何を意味しているのかを説明します。

|                  | 説明                                                        |
|:-----------------|:-----------------------------------------------------------|
| currentValue     | 変数(現在の状態) ※直接変更は不可                                |
| setCurrentValue  | 変数をセットする関数 ※変数の値を変更する際にはこれを使用しなければならない  |
| useState         | Reactから呼んだ関数                                           |
| initialValue     | 変数の初期値                                                 |

また上記構文はあまり見ない形式なので違和感を感じる人もいるかと思います。
これはJavaScriptのES2015で導入された構文で、**分割代入**(Destructuring assignment)というものの一例です。
ただuseStateを使用する際には、この書き方しかしないので**このように書くもの**として覚えておいても良いと思います。

実際に使用した場合の例を見てみましょう。
下記の例はボタンを押したときにStateを変化させてコンソールに表示しするものになります。

```react:App.js
import React, { useState } from 'react';  // useStateのimportが必要

const App = () => {
  // 宣言
  const [checkClicked, setCheckClicked] = useState("Not Clicked");

  const handleClick = () => {
    // Stateの変更
    setCheckClicked("Clicked!!");
    console.log(checkClicked);
  };

  return (
    <button onClick={handleClick}>Click me!</button>
  );
};
```
以上が簡単な例になります。これで関数コンポーネントでもStateを扱うことができます。

また**複数のStateを扱いたい場合には、それぞれに対応した宣言が必要になる**ことも抑えておきましょう。


#まとめ
今回は**React Hooksの簡単な説明とuseStateの使い方**について説明しました。
簡単にまとめたいと思います。

- **React Hooksとは**
  - stateやライフサイクルメソッドなど、クラスコンポーネントでしか扱えなかったものを関数コンポーネントでも使用できるようにする仕組み
- **useStateの使い方**
  - 宣言時にstateを持たせたい変数、その変数を変更するための関数、初期値を宣言する必要がある
  - `const [currentValue, setCurrentValue] = useState(initialValue);`

難易度としてはそこまで高くないので、実際に使用してみて理解を深めて見ると良いかと思います。


#参考資料

- [React公式](https://ja.reactjs.org/docs/hooks-intro.html)
- [最近Reactを始めた人向けのReact Hooks入門](https://sbfl.net/blog/2019/11/12/react-hooks-introduction/)
- [分割代入](https://ja.javascript.info/destructuring-assignment)