初心者必見！Reactの基本(状態管理ステートについて)

# 超有益資料
まず初めにこちらの資料は非常にわかりやすいです。ぜひ読んでみてください！

https://read-engineer.com/2020/12/11/react/#index_id5

# 有益Udemy
かなりいろんな内容が網羅されています。

https://www.udemy.com/course/react-complete-guide/

# この記事の続き

https://qiita.com/Hashimoto-Noriaki/items/ef41b035b1f520e9b92f

# 前提知識(仮想DOM)
Reactには```更新したデータの部分のみを変更する(仮想DOM)```がありこれがReactを使うメリットです。
***画面データの変更前と変更後の差分を検知して変更した箇所だけ更新***することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/1e2e0119-423f-2083-d6b3-c6d62608207b.png)
> 引用　https://read-engineer.com/2020/12/11/react/#index_id5


# ステートとは
仮想DOMによって画面のUIの変更がされUIが変わったという時に「UIが変わった」というサインはどのように判断するかについてです。
***コンポーネントにはそれぞれデータ(状態)を持たす***ことができ、
その状態の変更でUIが変更されたことを判断します。(Reactでは状態のことを```「State」```と呼びます。)

# useState
画面が変更されるための処理についてですが、コンポーネントに```再レンダリング```をお願いし、
新たな要素を作成してもらい、変更した値をどこかに保持してもらわなければならない。(```state```に保存)
これらをできるようにするのが```useState```です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/4a6b4f82-6071-3913-4ac4-dcc622c11556.png)
　> 引用　https://read-engineer.com/2020/12/11/react/#index_id5

```Paractice.js
import {useState} from "react";

const Practice = () => {//Practiceが再レンダリング
let [val,setVal] = useState(0);
  return (
    <>
      <input type="text"
      onChange={(e) => {
      setVal(e.target.value)}}//e,target.valueが値を保存しなければならない
      />{val}
    </>
  );
};

export default Practide;
```

# useStateの使い方
Reactの内部と接続し、状態が管理されます。現在の値と更新関数を返却し、
更新関数で新しい値をReactに渡します。
Reactのコンポーネントにも再実行をお願いします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/0c212f74-2886-9ea4-244b-9530f8dccce9.png)

>引用　https://takayamato.com/react-usestate/

# useStateでカウント機能
簡単なカウント機能を作成します。
useState(0)などは初期値です。```<></>```はfragmentです。

```Practice.js
import {useState} from "react";//useStateをインポート

const Practice = () => {
    const [count1,countSet1] = useState(0);//初期値
    const [count2,countSet2] = useState(10);//初期値
    const [count3,countSet3] = useState(100);//初期値
    return(
    <>//fragment
    <p>ボタン1を{count1}回</p>
    <button onClick={() =>{
        countSet1(count1 + 1);
    }}>ボタン1</button>
    <p>ボタン2を{count2}回</p>
    <button onClick={() =>{
         countSet2(count2 + 10);
    }}>ボタン2</button>
    <p>ボタン3を{count3}回</p>
    <button onClick={() =>{
         countSet3(count3 + 100);
    }}>ボタン3</button>
    </>
    )
};

export default Practice;
```
![スクリーンショット 2023-04-23 12.45.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/df52629f-8faa-a1b2-60e5-2d37d61b310b.png)

これはボタン1を1クリックで1カウント増えていき、ボタン2を1クリックで10カウント増えていき、
ボタン100を1クリックで100カウント増えていく機能です。

# useStateでカウント機能をもう一つ作成
state(count)がreactの中に保持されている値です。
const [count1,countSet1] = useState(0)が再レンダリングです。
***アロー関数にはreturnが省略***されます。

```Practice.js
import { useState } from "react";

const Example = () => {
    const [count,countSet] = useState(0);
    const countUP = () => {
        //countSet(count + 1);
        countSet(prevState => prevState+1);//この書き方にする
        // countSet(prevState => {//こんな書き方もある
        //     return prevState+1
        // });
    }
    const countDown = () => {
        countSet(count -1);
    }
    return(
    <> 
    <p>今のカウント数: {count}</p>
    <button onClick={countUP}>+</button>
    <button onClick={countDown}>-</button>
    </>
    )
};

export default Practice;
```
![スクリーンショット 2023-04-23 13.15.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/c3a2148d-41f2-6940-b0d0-91fd1d034c46.png)

+で;1カウント、-で-1カウントします。

# reactのstate更新用関数とレンダリングの図
これは```ChatGPIで聞いてみました```。あくまで参考までにお願いします。

```js
// Stateの初期値を設定する
const [count, setCount] = useState(0);

// Stateを更新する関数
const handleClick = () => {
  setCount(count + 1);
};
```
上記のコードは、useStateフックを使用して、countという名前のstateを定義しています。countの初期値は0であり、setCount関数はcountの値を更新するために使用されます。ボタンがクリックされると、handleClick関数が呼び出され、setCount関数がcountの新しい値をセットします。

以下の図は、Reactコンポーネントのstateが更新されたときにレンダリングされる流れを示しています。

```js
+----------------------+   +----------------------+
|                      |   |                      |
|   ComponentDidMount  |   |   setState({ count:   |
|                      |   |                0 })   |
+----------------------+   +----------------------+
           |                             |
           |                             |
           |                +-----------------------+
           |                |                       |
           +---------------->    Render count: 0     |
                            |                       |
                            +-----------------------+
                                        |
                                        |
                                        |
                           +------------------------+
                           |                        |
                           |   setState({ count:     |
                           |         count + 1 })     |
                           |                        |
                           +------------------------+
                                        |
                                        |
                                        |
               +------------------------+------------------------+
               |                        |                        |
               |     Render count: 1    |        Render count: 1  |
               |                        |                        |
               +------------------------+------------------------+

```

この図は、Reactコンポーネントが最初にマウントされたときにsetStateを使用して、count stateを0に設定する方法を示しています。それから、ユーザーがボタンをクリックしたときにsetStateを使用して、count stateをインクリメントします。count stateが変更されるたびに、Reactはコンポーネントを再レンダリングし、新しいcount値を表示します。 

> 引用　ChatGPI

# オブジェクトのステート
***オブジェクトのステートは新しくオブジェクトを設定しなめればいけません***。


```Practice.js
import { useState } from "react";

const Practice = () => {
const personObj = { name: "大谷", number: 17 };//初期値
const [person,setPerson] = useState(personObj);//useState

const changeName = (e) => {
setPerson({name:e.target.value,number:person.number})
}
const changeNumber = (e) => {
  setPerson({name:person.name,number:e.target.value})
}
const reset = () => {
  setPerson({name:"",number:""})//空
}
return (<>
 <h3>名前:{person.name}</h3>
 <h3>背番号:{person.number}</h3>
<input type = "text" value={person.name} onChange={changeName}/>
<input type = "number" value={person.number}onChange={changeNumber}/>
<div>
  <button onClick={reset}>リセット</button>
</div>
</>);
};

export default Practice;
```

![スクリーンショット 2023-04-23 18.08.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/f7050028-9373-e789-8fc6-e5f3d80800ee.png)

# 配列のステート
***新しい配列を書き換える場合は新しい配列を書き変える***必要があります。
```Practice.jsx
import {useState} from "react";
const Practice = () => {
  const scoreArray = [100, 50, 80, 40, 70];//配列
  const [score,setScore] = useState(scoreArray);//useState
  const shuffle = () => {
  const newScore = [...score];
  const value = newScore.pop();//popとunshiftを入れ替えたら数字がどんどんなくなる
  newScore.unshift(value);
  setScore(newScore);
 }
  return (
    <>
<h1>{score}</h1>
<button onClick={shuffle}>シャッフル</button>  
    </>
  );
};

export default Practice;
```
***pop() メソッドは、配列から最後の要素を削除して返します。***
***unshift() メソッドは配列の先頭に要素を追加し、配列のすべての要素のインデックス1つずつ増やします。***

![スクリーンショット 2023-04-24 11.19.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/44af6a63-dac6-ae5d-067b-3200385ecc8c.png)
シャッフルボタンを押すと数字が入れ替わります。

# ステートとコンポーネント
ステートとコンポーネントの関係をみていきます。

```Practice.js
import { useState } from "react";

const Practice = () => {
  const [toggle,setToggle] = useState(true);
  const toggleComponent = () => {
    setToggle(prev => !prev);//toggleのボタンを押すとカウントAとBの入れ替え
  }
  return(
    <>
    <button onClick={toggleComponent}>toggle</button>
    {toggle ? <Count title="カウントA"/> :<Count title="カウントB"/>}//三項演算子 
    {/* <Count title="カウントA"/>
    {toggle && <Count title="B"/>} */}//toggleボタンを押すとカウントBが初期化
    </>
  )
}

const Count = ({title}) => {
  const [count, setCount] = useState(0);
  const countUp = () => {
    setCount((prevstate) => prevstate + 1);
  };
  const countDown = () => {
    setCount(count - 1);
  };
  return (
    <>
      <h3>{title}: {count}</h3>
      <button onClick={countUp}>+</button>
      <button onClick={countDown}>-</button>
    </>
  );
};

export default Practice;
```

![スクリーンショット 2023-04-24 11.56.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/8c912374-b97f-fa62-d01c-8cebb47bec2d.png)

以下はChat GPIより参照です。

Reactにおけるコンポーネントは、UIの部品のようなものであり、状態を持つことができます。Reactでは、コンポーネントの状態はステート（state）と呼ばれます。ステートはコンポーネントが自己管理するプロパティであり、コンポーネント内で変更することができます。

Reactでは、ステートを変更すると、コンポーネントの再レンダリング（再描画）が行われます。つまり、ステートが変更されると、コンポーネントの表示も更新されます。

以下は、Reactコンポーネントとステートの関係を示す簡単な図です。
```
+-----------------------------------------------------+
|                 React Component                     |
|                                                     |
|  +-------------------+                              |
|  |                   |                              |
|  |   Component Tree  |                              |
|  |                   |                              |
|  +-------------------+                              |
|                                                     |
|  +-------------------+                              |
|  |                   |                              |
|  |      State        |     // ステートの管理         |
|  |                   |                              |
|  +-------------------+                              |
|                                                     |
|                                                     |
|                                                     |
|              React の仮想 DOM                        |
|                                                     |
+-----------------------------------------------------+

```

上記の図では、ReactのコンポーネントがComponent Treeという形で階層構造を形成しています。それぞれのコンポーネントは、自身のステートを持っており、そのステートを変更することでコンポーネントの表示も更新することができます。

Reactでは、ステートを変更するために setState メソッドを使用します。このメソッドは、ステートを更新するための関数を受け取り、その関数が返すオブジェクトでステートを上書きします。ステートを変更することで、Reactは変更を検知してコンポーネントを再レンダリングします。  

> 引用　ChatGPI

# ステートで複数のコンポーネント管理
stateでpropsを渡すケースについてです。

1. コンポーネントが消える時
2. 特定のstateを複数の子コンポーネントで共有したい時







# 資料

https://read-engineer.com/2020/12/11/react/#index_id5

http://shincode.info/2021/08/14/reacthook-about-usestate/

https://www.udemy.com/course/react-complete-guide/