【React】フック(Hook)を学ぼう！

# はじめに
この記事はstateを分かっている前提で進めていきます。  
stateがわからない人は[こちら](https://qiita.com/hotehote/items/4bedd167e5b69635364a)の記事から読んでもらえればと思います。

https://qiita.com/hotehote/items/4bedd167e5b69635364a

# フックとは
「フック」とはコンポーネントに「再利用可能な振る舞い」を付加するために用意されたものです。  
今では主流となったReact Hooks は React 16.8（2019 年 2 月リリース）で追加されました。  
では、このフックは何が便利なのでしょうか？  
それは、「関数コンポーネントで使える」ということです。ステートは本来、クラスコンポーネントでしか利用することができません。そのためこれまで関数コンポーネントでは値を操作して表示を変えることができませんでした。しかしフックの登場により関数コンポーネントでもステートのように値を管理することができるようになりました。  
関数コンポーネントとクラスコンポーネントの違いがわからない方は[こちら](https://fullstacklife.net/programming/react/ract-class-function-component/)

https://fullstacklife.net/programming/react/ract-class-function-component/

# useState

## useStateとは
useState()は関数コンポーネントでstateを管理するための機能です。初回のレンダー時に返されるstateはuseStateの第一引数に指定した値になります。

## 使い方
`const [state, stateを更新する関数] = useState(初期値);`と記述すると使用することができます。  
実際にコードで見ていきましょう！
```react
const [name, setName] = useState('');
const [age, setAge] = useState('');
const [form, setForm] = useState({name: '名無し', age: '0'});
```
このような感じで設定していきます。  
今回はフォームに入力した内容を表示していきます。
```react
import './App.css';
import { useState } from 'react';

function App() {
  const [name, setName] = useState('');
  const [age, setAge] = useState('');
  const [form, setForm] = useState({name: '名無し', age: '0'});

  function Profile() {
    return(
      <div>
        <p>
          名前：{form.name}さん
        </p>
        <p>
          年齢：{form.age}歳
        </p>
      </div>
    )
  }

  const handleSubmit = (e) => {
    e.preventDefault();
    setForm({name:name, age:age})
  };

  const handleChangeName = (e) => {
    setName(e.target.value);
  };

  const handleChangeAge = (e) => {
    setAge(e.target.value);
  };

  return (
    <div className="App">
      <Profile />
      <h1>プロフィール</h1>
      <form onSubmit={handleSubmit}>
        <div>
          <label htmlFor="name">名前</label>
          <input id="name" name="name" value={name} onChange={handleChangeName} />
        </div>
        <div>
          <label htmlFor="age">年齢</label>
          <input
            id="age"
            name="age"
            value={age}
            onChange={handleChangeAge}
            type='number'
            min="0"
          />
        </div>
        <div>
          <button type="submit">登録</button>
        </div>
      </form>
    </div>
  );
}

export default App;
```
するとこんな感じになります。
![image](https://firebasestorage.googleapis.com/v0/b/ciita-c6ea6.appspot.com/o/user%2Fimages%2F1kknVLPBuVgIA4zm?alt=media&token=be6d5d5f-cee0-4f7f-863c-9bed394c984c)

# useEffect
## useEffectとは
useEffect()は更新時に必要な処理を実行するものになります。

## 使い方
`useEffect(() => {
   実行したいこと
},[更新された値]) `と記述します。
第一引数に実行したいこと、第二引数にuseEffectを実行したい値を入れます。  
先程のコードを以下のように書きかえてみましょう！
```react
import './App.css';
import { useState, useEffect } from 'react';

function App() {
  const [name, setName] = useState('');
  const [age, setAge] = useState('');
  const [form, setForm] = useState({name: '名無し', age: '0'});
  const [msg, setMsg] = useState('');

  useEffect(() => {
    setMsg('僕の名前は'+ name + '探偵さ')
  }, [name])

  function Profile() {
    return(
      <div>
          {name &&
            <p>msg</p>
          }
        <p>
          名前：{form.name}さん
        </p>
        <p>
          年齢：{form.age}歳
        </p>
      </div>
    )
  }

  const handleSubmit = (e) => {
    e.preventDefault();
    setForm({name:name, age:age})
  };

  const handleChangeName = (e) => {
    setName(e.target.value);
  };

  const handleChangeAge = (e) => {
    setAge(e.target.value);
  };

  return (
    <div className="App">
      <Profile />
      <h1>プロフィール</h1>
      <form onSubmit={handleSubmit}>
        <div>
          <label htmlFor="name">名前</label>
          <input id="name" name="name" value={name} onChange={handleChangeName} />
        </div>
        <div>
          <label htmlFor="age">年齢</label>
          <input
            id="age"
            name="age"
            value={age}
            onChange={handleChangeAge}
            type='number'
            min="0"
          />
        </div>
        <div>
          <button type="submit">登録</button>
        </div>
      </form>
    </div>
  );
}

export default App;
```
するとこうなります。
![image](https://firebasestorage.googleapis.com/v0/b/ciita-c6ea6.appspot.com/o/user%2Fimages%2FHuwod01257VaMKiV?alt=media&token=4033f4ce-f2d4-447f-882f-e850b56ed2e8)

少し詳しくみていきましょう。  
まず、handleChangeNameで文字が入力される度にsetNameによってnameの値が更新されます。
```react
const handleChangeName = (e) => {
    setName(e.target.value);
  };
	
<div>
  <label htmlFor="name">名前</label>
  <input id="name" name="name" value={name} onChange={handleChangeName} />
</div>
```
次にこの部分でnameの値が変化した時、useEffect内の処理が実行されます。今回の場合、setMsgによってmsgの値が更新されます。
```react
useEffect(() => {
  setMsg('僕の名前は'+ name + '探偵さ')
}, [name])
```

そしてここで表示されます。  

```react
{name &&
    <p>msg</p>
}
```

# さいごに
ここまで読んでくださりありがとうございました。
フックはReactを勉強する上で必要不可欠になっています。この他にもフックの種類は何種類かあるので良かったら調べてみて下さい！ 

是非弊社開発課のXのフォローもよろしくです！
毎日エンジニアに向けた情報発信を行っています！

https://twitter.com/tech_cin