【React】3つの「propsの渡し方」から理解する、分割代入

## まえがき
```js
const { id, title, date } = eventData;
```
「なんだこの書き方は...？」となりがちなJavaScriptの記法、その1つが**分割代入**ではないでしょうか？

本記事は、**「分割代入という単語は知っているけれど仕組みはよく分かっていない」** あるいは、**「propsの渡し方がいくつかあって混乱している」** そんな悩みを解決する記事としてお届けします。

### 本記事で解説すること
- **基本を学ぼう**
	1. 「オブジェクト」とは？
    2. JavaScriptの「分割代入」とは？
	3. Reactの「props」とは？
- **3つの「propsの渡し方」**
	1. 分割代入は使わない `props.****`
	2. コンポーネント内で分割代入 `const { aaa, bbb } = props`
	3. 引数に分割代入 `const Xxxx = ({ aaa, bbb }) => {`

## 基本を学ぼう

### ①「オブジェクト」とは？
- オブジェクトは、**プロパティの集合**です。
- プロパティとは、**名前(key)と値(value)** が対になったものです。 
```js
{
  key1: value1, // ← この対がプロパティ
  key2: value2,
  key3: value3
} // ← この集合がオブジェクト
```
JavaScriptにおいては以下のようなものがオブジェクトですね！ 他にもイメージしやすいものだとCSSの記述方法もオブジェクトです。
```js
const eventData = {
  id: 6,
  title: "King & Prince デビュー6周年",
  date: "2024-05-23",
};
```
----
### ② JavaScriptの「分割代入」とは？
MDN Web Docsによると、
> 分割代入 (Destructuring assignment) 構文は、配列から値を取り出して、あるいはオブジェクトからプロパティを取り出して別個の変数に代入することを可能にするJavaScriptの式です。

とのことです。これがとても便利な構文です。

オブジェクトからプロパティを取り出す際には、ドット(.)を使ってプロパティを参照します。
```js
const eventData = {
  id: 6,
  title: "King & Prince デビュー6周年",
  date: "2024-05-23",
};
const title = eventData.title;
console.log(title);
```
::::details ドット(.)を使ってプロパティを参照していない場合
```js
const eventData = {
  id: 6,
  title: "King & Prince デビュー6周年",
  date: "2024-05-23",
};
console.log(title);
```

以下のようなエラーが発生します。```title```は未定義であると言われてしまっていますね。
:::message alert
Uncaught ReferenceError: title is not defined
:::
::::

この「プロパティを取り出す」という動作、プロパティが複数あると記述量が多くなってしまいます。
```js
const id = eventData.id;
const title = eventData.title;
const date = eventData.date;
```

これを解消するのが**分割代入**です！

分割代入は、**中カッコ{}に取り出したいプロパティを指定することで、配列やオブジェクトのプロパティ名(key)と同じ名前の変数が作れます**。次のサンプルコードは、上記のドット(.)を使ってプロパティを参照したコードと同等の処理になります。
```js: 分割代入
const { id, title, date } = eventDate;
// const id = eventData.id; などと同等の処理
```
なにやら、定義したオブジェクトを左右ひっくり返したような書き方ですね。これが冒頭に登場した分割代入です。
このように**複数のプロパティを一度に取り出すことができる**のが強みです。

----

### ③ Reactの「props」とは？
Reactにおいてコンポーネントとコンポーネントが互いにやりとりをする際に、共通の情報が必要になります。カレンダーなら予定のデータ、Todoアプリならタスクのデータもその1つですね。
Reactでは、このような**コンポーネントからコンポーネントへ渡される情報**のことを「**props**」と呼びます。
```jsx: コンポーネントＡ（情報を渡す側）
const ComponentA = () => {
  const userName = "髙橋海人";
  const email = "kaito.takahashi@kingandprince.co";

  return (
    <div>
      <h1>Hello, props!</h1>
      <p>これはコンポーネントとコンポーネントの間でpropsをやり取りする例です。</p>
      <ComponentB userName={userName} email={email} />
    </div>
  );
};
```
```jsx: コンポーネントＢ（情報を受け取る側）
const ComponentB = (props) => {
  return (
    <div>
      <h2>{props.userName}</h2>
      <p>{props.email}</p>
    </div>
  );
};
```
この受け渡されるpropsの中身、こんな感じです。
```js
console.log(props);
// Object {userName: "髙橋海人", email: "kaito.takahashi@kingandprince.co"}
```
実は、**propsってオブジェクトなんです**！
つまり、**オブジェクトの分割代入を利用してpropsは記述することができる**のです。


## 3つの「propsの渡し方」
さて、本題です。今回はそんな分割代入を使ったり使わなかったりして、propsの渡し方を紹介していきます！
 
### 1. 分割代入は使わないスタンダード `props.****`
- 引数は`props`、指定するときは`props.aaa`, `props.bbb`
```jsx: 1. 分割代入は使わないスタンダード
const Xxxx = (props) => {
    return (
        <p>propsとして渡した値を指定するには、{props.aaa}や{props.bbb}と記述します。</p>
    )
};

export default Xxxx;
```
最もスタンダードな、分割代入を使用しないパターンはこちらです！ Reactの入門的な教材はこちらの渡し方が多いのではないでしょうか？
#### メリット「propsであることのわかりやすさ」
- propsを渡して、どこで使用しているのかがひと目でわかりやすいため、Reactに慣れていく段階ではこちらが良いでしょう。これが入門教材に多い理由ですね。
#### デメリット「`props`の記述量が増える」
- proosとして渡した値を指定する際に、毎回`props.****`と記述する必要があるためpropsとして渡す値の数や、指定する回数が増えるほど記述量も比例して増えていきます。

----
### 2. コンポーネント内で分割代入 `const { aaa, bbb } = props`
- 引数は`props`、指定するときは`aaa`, `bbb`
- 関数コンポーネント内でpropsを分割代入
```jsx: 2. コンポーネント内で分割代入
const Xxxx = (props) => {
    const { aaa, bbb } = props;
    return (
        <p>propsとして渡した値を指定するには、{aaa}や{bbb}と記述します。</p>
    )
};

export default Xxxx;
```
propsは**オブジェクト**なので、**分割代入**を行うことができます！ それを活用した渡し方ですね。
#### メリット「引数も、propsも、記述を短くする」
- 関数コンポーネントの引数は先ほどと同じ`props`のままで、コンポーネント内でpropsを指定するときは、省略した形を使うことができます。毎回`props.****`と記述する必要がなくなりましたね。
#### デメリット「そもそも分割代入の書き方はわかりづらい」
- 冒頭で話した通り、分割代入は便利ではあるもののやはり書き方としてややわかりづらいのが難点です。

----
### 3. 引数に分割代入 `const Xxxx = ({ aaa, bbb }) => {`
- 引数は`{aaa, bbb}`、指定するときは`aaa`, `bbb`
- 関数コンポーネントの引数に直接分割代入
```jsx: 2. 引数に分割代入
const Xxxx = ({ aaa, bbb }) => {
    return (
        <p>propsとして渡した値を指定するには、{aaa}や{bbb}と記述します。</p>
    )
};

export default Xxxx;
```
これまでで最もスッキリとした見た目ではないでしょうか？ 筆者個人的には最も好きな書き方です。
#### メリット「見た目の簡潔さとわかりやすさ」
- 関数コンポーネントの引数にはじめからpropsに渡した値を記述することで、コンポーネント内でpropsを指定するときにそのまま省略した形を使うことができます。そもそも`props`と記述する必要も、分割代入の構文を記述する必要もなくなりましたね。
#### デメリット「propsに渡す値の数が多いと、引数の記述量が増える」
- もしpropsに10個くらい値が渡されていたら、関数コンポーネントの引数に記述する内容が多くなってしまいますね。その場合はメリットである簡潔さがやや失われてしまいます。


## おわりに
ここまで、Reactのpropsの渡し方を３つご紹介してきました。
1と2だけを知ると、結局propsの分割代入がどういうものかイメージしづらいですが、3を知るとよりpropsの分割代入も理解が深まるはずです。
メリットとデメリットを考えながらpropsの渡し方にもこだわってReactを使ってみましょう！

## 参考文献
- [MDN Web Docs 分割代入](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)
- [サバイバルTypeScript オブジェクトの分割代入 (destructuring assignment)](https://typescriptbook.jp/reference/values-types-variables/object/destructuring-assignment-from-objects)
- [[React] 関数コンポーネントのpropsの渡し方と分割代入](https://qiita.com/cha_ayu418/items/7fe607bec2b4acf8b8d3)
- [【React】関数コンポーネントの引数（props）は分割代入で渡すとわかりやすい](https://dezanari.com/react-component-props-object/)