[React] Props

# 環境
MacBook Pro (2.3 GHz 8コアIntel Core i9)
macOS 14.0（23A344）
Homebrew 4.3.8
gh 2.52.0

# まとめ
## Propsとは
> React コンポーネントは互いにやりとりをする際に props というものを使います。親コンポーネントは子コンポーネントに props を渡すことで情報を伝えることができるのです。props は HTML の属性と似ていると思われるかもしれませんが、props ではオブジェクトや配列、関数などのあらゆる JavaScript の値を渡すことができます。

[コンポーネントに props を渡す](https://ja.react.dev/learn/passing-props-to-a-component)

つまり、
**`Props`は、Reactコンポーネント間でデータを渡すための仕組み**
**`Props`は、コンポーネントに対して`引数`のような役割を果たし、親コンポーネントから子コンポーネントへ情報（オブジェクトや配列、関数などのあらゆる JavaScript の値）を渡す**

## なぜPropsが必要なのか
1. コンポーネント間のデータ共有
1. 再利用性の向上: 汎用的なコンポーネントを作成できる
1. ステートと組み合わせた動的UI 

## PropsとStateの違いは？
|特徴|`Props`|`State`|
|:--|:-:|:-:|
|変更可能性|読み取り専用（不変）|変更可能（可変）|
|管理場所|親コンポーネント|コンポーネント自身|
|データの流れ|親から子へ（単方向データフロー）|コンポーネント内部のみ|
|役割|外部データの受け渡し|内部状態の管理|
|更新方法|親コンポーネントで値を変更|`setState`や`useState`を使って変更|

## 親コンポーネント、子コンポーネントとは
Prposという視点のみから考えると以下

親コンポーネント: `Props`を`渡す`コンポーネント
子コンポーネント: `Props`を`受け取る`コンポーネント

~~~:e.g._folda_structure
├── public/
│   ├── index.html
└── src/
│   ├── index.js(index.jsx)  (ここではインラインスタイルでCSSを記述)
│   ├── App.js(App.jsx)      ← 親コンポーネント
│   └── components/
│   │   ├── ColorfulMessage.jsx/  ← 子コンポーネント
│   │   └── Other/
~~~

# ソースコード
## 1. 子コンポーネント、Propsを使わない場合
### フォルダ
~~~:folda_structure
├── public/
│   ├── index.html
└── src/
│   ├── index.js(index.jsx)  (ここではインラインスタイルでCSSを記述)
│   └──  App.js(App.jsx)      
~~~
### JavaScript
~~~diff_jsx:App.js
export const App = () => {
  const onClickButton = () => alert();
  const contentStyleA = {
    color: "blue",
  };
  const contentStyleB = {
    color: "green",
  };
  return (
    <>
      <h1>こんにちは!</h1>
      <p style={contentStyleA}>お元気ですか？</p>
      <p style={contentStyleB}>元気です!</p>
      <button onclick={onClickButton}>ボタン</button>
    </>
  );
};
~~~

## 2. 子コンポーネントを使う場合
### フォルダ
~~~:folda_structure
├── public/
│   ├── index.html
└── src/
│   ├── index.js(index.jsx)  (ここではインラインスタイルでCSSを記述)
│   ├── App.js(App.jsx)      ← 親コンポーネント
│   └── components/
│   │   ├── ColorfulMessage.jsx/  ← 子コンポーネント
│   │   └── Other/
~~~

### JavaScript
~~~diff_jsx:App.js
+import { ColorfulMessage } from "./components/ColorfulMessage";

export const App = () => {
  const onClickButton = () => alert();
- const contentStyleA = {
-   color: "blue",
- };
  const contentStyleB = {
    color: "green",
  };
  return (
    <>
      <h1>こんにちは!</h1>
-     <p style={contentStyleA}>お元気ですか?</p>
+     <ColorfulMessageage />
      <p style={contentStyleB}>元気です!</p>
      <button onclick={onClickButton}>ボタン</button>
    </>
  );
};
~~~

~~~diff_jsx:ColorfulMessage.jsx
export const ColorfulMessage = () => {
  const contentStyleA = {
    color: "blue",
  };

  return <p style={contentStyleA}>お元気ですか？</p>;
};
~~~

## 3. 子コンポーネント、Propsを使う場合
### フォルダ
~~~:folda_structure
├── public/
│   ├── index.html
└── src/
│   ├── index.js(index.jsx)  (ここではインラインスタイルでCSSを記述)
│   ├── App.js(App.jsx)      ← 親コンポーネント
│   └── components/
│   │   ├── ColorfulMessage.jsx/  ← 子コンポーネント
│   │   └── Other/
~~~

### JavaScript
~~~diff_jsx:App.jsx
import { ColorfulMessage } from "./components/ColorfulMessage";

export const App = () => {
  const onClickButton = () => alert();
  const contentStyleB = {
    color: "green",
  };
  return (
    <>
      <h1>こんにちは!</h1>
-     <ColorfulMessageage />      
+     <ColorfulMessageage color="blue" message="お元気ですか？" />
      <p style={contentStyleB}>元気です!</p>
      <button onclick={onClickButton}>ボタン</button>
    </>
  );
};
~~~

~~~diff_jsx:ColorfulMessage.jsx
-export const ColorfulMessage = () => {
+export const ColorfulMessage = (props) => {
  const contentStyleA = {
-   color: "blue",
+   color: props.color,
  };

- return <p style={contentStyleA}>お元気ですか？</p>;
+ return <p style={contentStyleA}>{props.message}</p>;
};
~~~

## 4. 他の`p`タグにもPropsを応用する
### JavaScript
~~~diff_jsx:App.jsx
import { ColorfulMessage } from "./components/ColorfulMessage";

export const App = () => {
  const onClickButton = () => alert();
- const contentStyleB = {
-   color: "green",
- };
  return (
    <>
      <h1>こんにちは!</h1>    
      <ColorfulMessageage color="blue" message="お元気ですか？" />
-     <p style={contentStyleB}>元気です!</p>
+     <ColorfulMessageage color="green" message="元気です!" />
      <button onclick={onClickButton}>ボタン</button>
    </>
  );
};
~~~

~~~diff_jsx:ColorfulMessage.jsx
export const ColorfulMessage = (props) => {
  const contentStyleA = {
    color: props.color,
  };

  return <p style={contentStyleA}>{props.message}</p>;
};
~~~

# イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/50464bb9-97ba-4886-ecb8-e4a6a66face6.png)

# Applied
## `h1`、`p`タグと同様に閉じタグで実装したい時（可読性向上）
`h1`、`p`タグと同様に閉じタグを使ってPropsを受け渡すことこもできる

~~~diff_jsx:App.jsx
import { ColorfulMessage } from "./components/ColorfulMessage";

export const App = () => {
  const onClickButton = () => alert();
  return (
    <>
      <h1>こんにちは!</h1>    
-     <ColorfulMessageage color="blue" message="お元気ですか？" />
+     <ColorfulMessageage color="blue">お元気ですか？<ColorfulMessageage/>
+     // or
+     <ColorfulMessageage color="blue" message="お元気ですか？"><ColorfulMessageage/>
-     <ColorfulMessageage color="green" message="元気です!" />
+     <ColorfulMessageage color="green">元気です!<ColorfulMessageage/>
+     // or
+     <ColorfulMessageage color="green" message="元気です!"><ColorfulMessageage/>
      <button onclick={onClickButton}>ボタン</button>
    </>
  );
};
~~~

~~~diff_jsx:ColorfulMessage.jsx
export const ColorfulMessage = (props) => {
  const contentStyleA = {
    color: props.color,
  };

- return <p style={contentStyleA}>{props.message}</p>;
+ return <p style={contentStyleA}>{props.children}</p>;
+ // or
+ return <p style={contentStyleA}>{props.message}</p>;
};
~~~

## Propsが多い時（可読性向上）
[分割代入](https://qiita.com/Jochun/items/c6151402d083ad17ea9c)を用いる
~~~diff_jsx:App.jsx
import { ColorfulMessage } from "./components/ColorfulMessage";

export const App = () => {
  const onClickButton = () => alert();
  return (
    <>
      <h1>こんにちは!</h1>    
      <ColorfulMessageage color="blue">お元気ですか？<ColorfulMessageage/>
      <ColorfulMessageage color="green">元気です!<ColorfulMessageage/>
      <button onclick={onClickButton}>ボタン</button>
    </>
  );
};
~~~

~~~diff_jsx:ColorfulMessage.jsx
export const ColorfulMessage = (props) => {
+ const { color , children} = props
  const contentStyleA = {
-   color: props.color,
+   color: color,
  };

- return <p style={contentStyleA}>{props.children}</p>;
+ return <p style={contentStyleA}>{children}</p>;
};
~~~

# 参考リンク
- [コンポーネントに props を渡す](https://ja.react.dev/learn/passing-props-to-a-component)
- [モダンJavaScriptの基礎から始める挫折しないためのReact入門
](https://www.udemy.com/course/modern_javascipt_react_beginner)