Reactを学ぶX 〜ReactHooks〜

## ■ はじめに

タイトルについて記事にしました。
この記事で得る内容は以下の通りです。

・ Reactの基礎知識が増える
・ ReactHooksについて

## ■ フック（hook）とは

・ クラスの機能（stateやライフサイクル）をFunctional Componentでも使える

・ React 16.8から導入（2020年2月に正式リリース）

・ 100%後方互換　→　<font color="red">ReactHooksと従来記述していた構文は干渉しない</font>

→ ただ、あくまでReactHooksは選択肢の一つであり、Class Componentを置き換えるものではない

## ■ なぜフックを使うのか？

#### A. シンプルさを保つため

・ Class Componentは難しい

→ `this`がReactは他言語と比べ異なる挙動をするので、なるべく使いたくない
　ですが、Class Componentを使うと、どうしても`this`を使わないといけない

→ stateを扱うロジックが複雑

→ 複数のライフサイクルメソッドに（同じような）副作用のあるメソッドがまたがる

```react:sample.jsx
componentDidMount() {
    this.counter.addEventListener(
        'click', this.countUp
    )
}
componentWillUnmount() {
    this.counter.removeEventListener(
        'click', this.countUp
    )
}

// 前回のいいねボタンは、componentDidMountでイベントリスナーを設定して、componentWillUnmountでイベントリスナーを解除していた
// 時間の流れでコードを分けるのではなくて、一つの機能を一つの場所にまとめて書いておく方がわかりやすい
```

これらの課題を解決する手段として、次第にフックが使われ始めました

## ■ usestate()メソッド

・ Functional Copmponentでもstateを使う方法

・ ステートフックと呼ばれている

・ Class Componentでいう`this.state`と`setState`の代替

・ 複数のstateを扱う時は、usestate()をstate毎に宣言します

## ■ usestate()メソッドの使い方

```react:sample.jsx
// ① useState関数をインポート
import React, {useState} from 'react';

// ② 宣言をする
const [isPublished, togglePublished] = useState(false);
//    state変数名    state変更関数名　　　　　　　　 state初期値

// ③ JSX内で使う
<input /** 中略 */ onClick={() => togglePublished(!isPublished)}/>
// 例：inputタグでクリックされたら、stateを変更する関数を呼び出して、isPublishの値を反転させる

```

## ■ 例

前使っていたプロジェクトのBlog.jsxとArticle.jsxを使って
Blog.jsxで記述していたBlogクラスをFunctional Componentに置き換えます

✳︎今回、不要な所をコメントアウトしています

```react:Blog.jsx
import React from "react";
import Article from "./Article";
import * as FooBar from "./components/FooBar";
import Hoge from "./components/Hoge";

const Blog = () => {
  // componentDidMount() {
  //   // ボタンがクリックされたらいいねをカウントアップする
  //   document.getElementById("counter").addEventListener("click", this.countUp);
  // }

  // componentDidUpdate() {
  //   if (this.state.count >= 10) {
  //     this.setState({ count: 0 });
  //   }
  // }

  // componentWillUnmount() {
  //   document.getElementById("counter").removeEventListener("click", this.countUp);
  // }

  // countUp = () => {
  //   this.setState({
  //     count: this.state.count + 1,
  //   });
  // };

  return (
    <>
      <Article
        title={"Reactの使い方"}
        // count={this.state.count}
      />
      <FooBar.Foo />
      <FooBar.Bar />
      <Hoge />
    </>
  );
};

export default Blog;
```

Functional ComponentだったArticle.jsxは、stateを持つことができませんでしたが
usestate()メソッドを使うことで、stateを持たせることができます

```react:Article.jsx
import React, { useState } from "react"; // useStateを使えるようにする
// import LikeButton from "./LikeButton";

const Article = (props) => {
  const [isPublished, togglePublished] = useState(false); // useStateメソッド（state変数名・stateを変更する変数名・useState初期値）

  return (
    <div>
      <h2>{props.title}</h2>
      <label htmlFor="check">公開状態：</label>
      <input type="checkbox" checked={isPublished} id="check" onClick={() => togglePublished(!isPublished)} />
      {/* <LikeButton count={props.count} /> */}
    </div>
  );
};

export default Article;
```

チェックボックスをクリックしたら、useStateで作ったtogglePublishedの引数(isPublished)を渡して!でFalseを反転させます

![functionalでも使える.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/0ef17e54-95ae-d631-d677-1e112c904bd9.gif)

Functional Componentでもstateを扱う事ができて、同時にstateの変更も行えるようになります