Reactを基本からまとめてみた【8】【React Hook (useState)②】

##はじめに
####学習するに至った経緯
2020年より、未経験からエンジニアへの転職を目指し、某プログラミングスクールへ通う。入学後、『Ruby』を未経験から学ぶ人が多いのと『Ruby』の求人が思っていた以上に少ないので、卒業後、フロントエンドのエンジニアを目指す事に。
Reactの学習した事を言語化し、認識の深化による備忘録として記載。

##useStateとは
関数コンポーネント内でstateを保持するためのフック。

##フック(Hookとは)
React16.8で追加された新機能で、関数コンポーネントにstateやライフサイクルといったReactの機能を"接続する(hook into)"ための関数のこと。

##useStateを使うと何ができるのか
useStateを用いることで、コンポーネントに状態(state)を持たせることができる。
状態(state)とは、コンポーネントに管理され、プライベートであるべき値のこと。

##注意点
##### フックを呼び出すのはトップレベルのみ

・　フックは条件分岐等では呼び出さない。
・　フックは呼び出される順番で状態を管理している。
・　毎回同じ順番で呼び出さないとバグの原因となる。

##### クラスコンポーネントではフックは使えない

##実際にコーディングしてみる
####useStateの動作確認用のアプリを用意
#####create-react-appのtypescriptテンプレートを使用

```
terminal
npx create-react-app <ファイル名> --template typescript
or
yarn create react-app <ファイル名> --template typescript
```
####countアプリで基本の動きを理解
① src / components / Counter.tsxを作成する 
② App.tsxとCounter.tsxを作成する

```App.tsx
import React from 'react';
import Counter from './components/Counter';
import './App.css';

function App() {
  return (
    <div className="App">
      <Counter />
    </div>
  );
}
export default App;
``` 
```Counter.tsx
import React from 'react'
const Counter: React.VFC = () => {
    return <div>Counter</div>;
};
export default Counter;
```

#####(1)：一般的な書き方

```Counter.tsx
import React, {useState} from 'react'

const Counter: React.VFC = () => {
    const [count, setCount] = useState(100);
    return <button onClick={() => setCount(count + 1)}>{count}</button>;
};
export default Counter;
```

#####(2)：新しいstateが前のstateに基づいて計算される場合

```Counter.tsx
import React, { useState } from 'react';

const Counter: React.VFC = () => {
    const [count, setCount] = useState(100);
    return (
    <button 
      onClick={() => {
        setCount((prevCount) => prevCount + 1);
        setCount((prevCount) => prevCount + 1);
     }}
    >
    {count}
  </button>
  );
};
export default Counter;
```

#####(3)：初期値の計算に時間がかかる場合

```Counter.tsx
import React, { useState } from 'react';

function initializeCounter() {
    for (let i = 0; i < 20000; i++) {
        console.log(i);
    }
return 0;
}

const Counter: React.VFC = () => {
    const [count, setCount] = useState(() => {
        const initialValue = initializeCounter();
        return initialValue;
    });
    return (
    <button 
      onClick={() => {
        setCount((prevCount) => prevCount + 1);
        setCount((prevCount) => prevCount + 1);
     }}
    >
    {count}
  </button>
  );
};
export default Counter;
```

##入力フォームをuseStateで管理する

src / components / InputForm.tsx
①：１つのステートフックで複数の入力フォームの状態を管理

```InputForm.tsx
import React, { useState } from 'react';

const InputForm: React.VFC = () => {
    const [name, setName] = useState({first: '', last:''});
  return (
    <div>
      <input 
      value={name.first} 
      onChange={(e)=>
      setName((prevName)=>({
          first:e.target.value,
          last:prevName.last,
          }))
          }
          />
      <input
      value={name.last} 
      onChange={(e)=>
      setName((prevName)=>({
          ...prevName,
          last:e.target.value,
          }))
          }
      />
      <p>
      {name.first}
      {name.last}
      </p>
    </div>
  );
};

export default InputForm;
```

②：複数のステートフックで複数の入力フォームの状態を管理

```InputForm.tsx
import React, { useState } from 'react';

const InputForm: React.VFC = () => {
    // const [name, setName] = useState({first: '', last:''});
    const [firstName, setFirstName] = useState('');
    const [lastName, setLastName] = useState('');
  return (
    <div>
      <input 
    //   value={name.first} 
    //   onChange={(e)=>
    //   setName((prevName)=>({
    //       first:e.target.value,
    //       last:prevName.last,
    //       }))
    //       }
    value={firstName}
    onChange={(e)=> setFirstName(e.target.value)}
          />
      <input
    //   value={name.last} 
    //   onChange={(e)=>
    //   setName((prevName)=>({
    //       ...prevName,
    //       last:e.target.value,
    //       }))
    //       }
    value={lastName}
    onChange={(e)=> setLastName(e.target.value)}
      />
      <p>
      {/* {name.first}
      {name.last} */}
      {firstName}
      {lastName}
      </p>
    </div>
  );
};

export default InputForm;
```

##①と②のどちらを使うか
②を使う。
理由：コードがシンプルになる。変数名でどんな状態を管理しているかわかりやすい。

##参考サイト
[【ReactHooks入門】第2回：useStateの理解]
(https://www.youtube.com/watch?v=sAtKilNWslo)
[【React Hooks】useStateの基本を理解しよう]
(https://tyotto-good.com/blog/usestate-basic)