Reactの基本、状態管理(props)

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

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



# propsとstateとは
```props```は***親コンポーネントで定義した状態を子コンポーネントへ値を渡す仕組み***です。
```state```は***各コンポーネントに持つ、コンポーネントの状態を管理する仕組み***です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/70f66d69-723e-dff3-472b-1884155da9d2.png)

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

状態管理は基礎なので抑えておく必要があります。この記事ではpropsを説明します。

### 親子関係
コンポーネントの親子関係は以下のような関係があります。

```親 : コンポーネントを利用する側```
```子 : コンポーネントを利用される側```

# propsを使う
まず***親コンポーネントは子コンポーネント呼び出す時にに、子コンポーネントに渡したい値を設定***し、
***子コンポーネントは親から値をもらいたいところにprops***を定義します。

⚫︎***親コンポーネント***
```Practice.js
import Child from "./components/Child";

const Practice = () => <Child color="green" />;
export default Practice;
```
***●子コンポーネント***
```Child.js
import "./Child.css";

const Child = (props) => {//props定義
  //console.log(props);//中身確認

  return (
    <div className={`component ${props.color}`}>//props定義
      <h3>React学習</h3>
    </div>
  );
};

export default Child;
```
CSSはここでは省略します。

![スクリーンショット 2023-04-09 5.31.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/ba9187dd-337d-9d76-e28f-0174df9970a2.png)

追加で***実はpropsと書かなくても実装はできます。***
propsと書かなくても文法上は実装できますが、propsだとわかりやすいので書いています。
propsのとこをpropsと書かずに```{}```を使います。***分割代入というJSのやり方***です。

```Practice.js
import Child from "./components/Child";

const Practice = () => {
  return (
    <>
      <Child color="" />
      <Child color="green" />
    </>
  );
};
export default Practice;

```
fragmentの書き方も追加してあります。<>, </>です。
```Child.js
import "./Child.css";

const Child = ({ color }) => {
  return (
    <div className={`component ${color}`}>
      <h3>React学習</h3>
    </div>
  );
};

export default Child;
```

![スクリーンショット 2023-04-09 5.43.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/e56860d2-9c07-01c0-cc25-ac08081c3017.png)


初期値をピンク色に設定してみます。CSSは今回も省略です。
```Practice.js
import Child from "./components/Practice";

const Example = () => {
  return (
    <>
      <Child />
      <Child color="green" />
    </>
  );
};
export default Practice;
```

```Child.js
import "./Child.css";

const Child = ({ color = "pink" }) => {
  return (
    <div className={`component ${color}`}>
      <h3>React学習</h3>
    </div>
  );
};

export default Child;
```

![スクリーンショット 2023-04-09 5.48.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/e287ff14-69f5-1c6b-2a32-ce4a60dd0dbb.png)

こんな感じでも書き換えできるみたいです。
```Child.js
import "./Child.css";

const Child = ({ color: c = "pink" }) => {
  return (
    <div className={`component ${c}`}>
      <h3>React学習</h3>
    </div>
  );
};

export default Child;
```

# いろんなpropsで値を渡す
#### ```数字の渡し方```

●子コンポーネント
```Child.js
import "./Child.css";

const Child = ({ color: c = "pink", num }) => {
  return (
    <div className={`component ${c}`}>
      <h2>React学習</h2>
      <h2>{num}</h2>
    </div>
  );
};

export default Child;
```
●親コンポーネント
```Practice.js
import Child from "./components/Child";

const Practice = () => {
  return (
    <>
      <Child num={1000} />　//ここで数字
      {/*<Child color="green" />*/}
    </>
  );
};
export default Practice;
```
CSSは省略します。

![スクリーンショット 2023-04-09 17.32.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/3d1e9211-0969-e285-2423-18c42f0e4c16.png)

#### 　関数の渡し方
```Practice.js
import Child from "./components/Child";

const Practice = () => {
  const greeting = (arg) => `こんにちは${arg}`;
  return (
    <>
      <Child num={1000} fn={greeting} />　
    </>
  );
};
export default Practice;
```

```Child.js
import "./Child.css";

const Child = ({ color: c = "pink", num, fn }) => {
  return (
    <div className={`component ${c}`}>
      <h2>React学習</h2>
      <h2>{num}</h2>
      <h2>{fn("マークさん")}</h2>
    </div>
  );
};

export default Child;
```

![スクリーンショット 2023-04-09 17.39.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/3b5bce97-6be1-c420-359c-de6f2f2e6825.png)


#### 真偽値
booleanを定義していきます。

```Practice.js
import Child from "./components/Child";

const Example = () => {
  const greeting = (arg) => `こんにちは${arg}`;

  return (
    <>
      <Child num={1000} fn={greeting} boolean />
      {/*<Child color="green" />*/}
    </>
  );
};
export default Practice;
```

```Child.js
import "./Child.css";

const Child = ({ color: c = "pink", num, fn, boolean }) => {
  return (
    <div className={`component ${c}`}>
      <h2>React学習</h2>
      <h2>{num}</h2>
      <h2>{fn("マークさん")}</h2>
      <h2>{boolean ? "true" : "false"}</h2>
    </div>
  );
};

export default Child;
```
trueが出力されます。booleanがなくなるとfalseになります。
```Practice.js
 return (
    <>
      <Child num={1000} fn={greeting} />
      {/*<Child color="green" />*/}
    </>
  );
```
理由はここで三項演算子を書いてあるからです。
```
  <h2>{boolean ? "true" : "false"}</h2>
```

#### オブジェクト
オブジェクトも見ていきます。

```Practice.js
import Child from "./components/Child";

const Practice = () => {
  const greeting = (arg) => `こんにちは${arg}`;

  return (
    <>
      <Child
        num={1000}
        obj={{ name: "Messi", age: 35 }}
      />
    </>
  );
};
export default Practice;
```

```Child.js
import "./Child.css";

const Child = ({ color: c = "pink", num, obj }) => {
  return (
    <div className={`component ${c}`}>
      <h2>React学習</h2>
      <h2>{num}</h2>
      <h2>{obj.name + "は" + obj.age + "です"}</h2>
    </div>
  );
};

export default Child;
```

![スクリーンショット 2023-04-09 18.11.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/ea60aead-6160-273a-f2df-8c394e3e3519.png)

#### 簡単な書き方

```Practice.js
import Child from "./components/Child";

const Example = () => {
  const greeting = (arg) => `こんにちは${arg}`;
  const Object = {
    color: "green",
    num: 1000,
  };
  return (
    <>
      <Child
        {...Object}
        boolean
        obj={{ name: "Messi", age: 35 }}
      />
    
    </>
  );
```
```{...Object}```にしたのはObject.colorなどで書くのが面倒なのでこのように書けます。
これはスプレッド演算子です。


# children
***テキスト情報をPropsで受け渡す特殊なprops***です。

```react
const Example = () => {
  return (
    <div>
      <Container title="Children学習">{100}</Container>
    </div>
  );
};
```
```react
const Container = ({ title, children }) => {
  return (
    <div className="container">
      <h3>{title}</h3>
      <h3>{children}</h3>
      <Profile />
    </div>
  );
};
```

別の書き方です。
```react
const profile = [
  {name: "大谷", age: 28},
  {name:"メッシ",age:35},
];

const Example = () => {
  return (
    <div>
      <Container title="Childrenとは？">
        children={[<Profile {...profile[0]} />, <Profile {...profile[1]} />]}/
      </Container>
    </div>
  );
};
```
{}の中身が出力されます。


https://devsakaso.com/react-props-children


# propsのルール
1. ```子から親へ値を渡せない、つまり読みこむのみ```
2. ```propsの値を動的に変更できない、つまりpropsの流れは一方通行```

まずは２からです。
```Practice.js
//省略
const Practice = () => {
  const dogName = "ポチ";
  const catName = "たま";

  return (
    <>
      <Hello dogName={dogName} />
      <Bye catName={catName} />
    </>
  );
};

export default Practice;
```

```Dog.js
const Dog = (props) => {
  return (
    <div>
      <h3>Dog: {props.dogName}</h3>
    </div>
  );
};

export default Dog;
```

```Cat.js
const Cat = (props) => {
  return (
    <div>
      <h3>Cat: {props.catName}</h3>
    </div>
  );
};

export default Cat;
```
```
Dog: ポチ
Cat: たま
```
と出力

続いて１です。

```Dog.js
const Hello = (props) => {
  props.dogName = "シロ";
  console.log(dogName);
  return (
    <div>
      <h3>Hello: {props.dogName}</h3>
    </div>
  );
};
```
propsで名前の書き換えはできないです。
```
Uncaught TypeError: Cannot assign to read only property 'dogName' of object '#<Object>'
```
このようなエラーが出てきます。

# JSXとは
ReactによってJSの構文を拡張したもので、JSのオブジェクトに変換されます。



# 資料

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

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

https://qiita.com/rio_threehouse/items/7632f5a593cf218b9504