Next.jsで学ぶReact講座(完全初心者向け・30日) | 第2章:Reactの基本操作 – props(データの受け渡し)

Next.js
スポンサーリンク

propsとは何か

「コンポーネントに渡す“引数”のようなもの」

props(プロップス)は、React コンポーネントに渡す「データの入れ物」です。
少しプログラミング寄りに言うと、「コンポーネント版の関数の引数」というイメージが一番近いです。

普通の関数を思い出してください。

function greet(name) {
  console.log("こんにちは、" + name + " さん");
}

greet("太郎");
greet("花子");
JavaScript

このとき name が「引数」で、呼び出し側から「太郎」「花子」という値を渡しています。

React コンポーネントでも、まさに同じことをやります。
「コンポーネントに外から値を渡して、その値に応じて表示を変える」ためのしくみが props です。

超シンプルに書くとこうなります。

function Greeting(props) {
  return <p>こんにちは、{props.name} さん!</p>;
}
JSX

この props の中に、「外から渡される値」が入ってきます。


親 → 子へのデータ渡し

コンポーネント同士の“会話”は一方通行(上から下)

React では、データの流れは基本的に「親コンポーネント → 子コンポーネント」です。
親が子に「これ使ってね」とデータを渡す感じです。

簡単な例を作ってみます。
親コンポーネントが Greeting を呼び出し、名前を渡すパターンです。

function Greeting(props) {
  return <p>こんにちは、{props.name} さん!</p>;
}

export default function Page() {
  return (
    <main>
      <Greeting name="太郎" />
      <Greeting name="花子" />
    </main>
  );
}
JSX

ここで起きていることを整理します。

Page コンポーネントが「親」
Greeting コンポーネントが「子」
親の中で <Greeting name="太郎" /> と書いている
このとき name="太郎" という形で、「name という props に ‘太郎’ を渡す」ことになる

Greeting 側では、props.name としてその値を受け取れます。
つまり、「親がタグの属性として渡す → 子が props 経由で受け取る」という流れです。

複数の値を渡すことも普通にできる

props は複数同時に渡せます。
たとえば、ユーザー名と年齢をまとめて表示する子コンポーネントを考えます。

function UserInfo(props) {
  return (
    <p>
      名前:{props.name} / 年齢:{props.age}
    </p>
  );
}

export default function Page() {
  return (
    <main>
      <UserInfo name="太郎" age={20} />
      <UserInfo name="花子" age={25} />
    </main>
  );
}
JSX

親は <UserInfo name="太郎" age={20} /> のように、HTML の属性っぽい書き方で渡します。
子は props.nameprops.age でその値を使います。

ここで age={20} のように、数値や式を渡すときに {} を使うことも重要なポイントです。


propsを表示する

props オブジェクトから値を取り出して JSX に埋め込む

props は「オブジェクト」です。
さっきの例では、props はだいたいこんなイメージの中身を持っています。

{ name: "太郎", age: 20 } のような形です。

それを props.nameprops.age で取り出して、JSX の {} の中に埋め込んでいきます。

もう少しだけ整理された書き方として、「分割代入」を使う方法があります。

function UserInfo(props) {
  const { name, age } = props;

  return (
    <p>
      名前:{name} / 年齢:{age}
    </p>
  );
}
JSX

あるいは、関数の引数のところで直接分割してしまうこともよくあります。

function UserInfo({ name, age }) {
  return (
    <p>
      名前:{name} / 年齢:{age}
    </p>
  );
}
JSX

どちらも意味は同じで、

「このコンポーネントは props の中から name と age を使いますよ」

と宣言している感じです。

JSX での表示の基本パターン

props を表示するときの基本パターンは、とてもシンプルです。

テキストの中に {props.xxx} または {xxx} を埋め込む
必要なら文字列とくっつける

例えば、挨拶コンポーネントを少しだけ丁寧にしてみます。

function Greeting({ name, time }) {
  return (
    <p>
      {time}{name} さん。
    </p>
  );
}

export default function Page() {
  return (
    <main>
      <Greeting name="太郎" time="おはよう" />
      <Greeting name="花子" time="こんばんは" />
    </main>
  );
}
JSX

ブラウザには、

「おはよう、太郎 さん。」
「こんばんは、花子 さん。」

と表示されます。

Greeting は「挨拶の形(テンプレート)」だけを持っていて、
具体的な名前や時間帯は親から props として渡している、という構造です。


propsのよくあるミス

1. props を受け取る引数を書き忘れる

超よくあるパターンです。

子コンポーネント側で props を引数に書き忘れてしまうと、props が未定義のままになり、エラーになります。

例えば、これはダメな例です。

function Greeting() {
  return <p>こんにちは、{props.name} さん!</p>;
}
JSX

この場合、関数の引数に props を書いていないので、props 自体が存在しません。
正しくはこうです。

function Greeting(props) {
  return <p>こんにちは、{props.name} さん!</p>;
}
JSX

もしくは分割代入を使うならこうです。

function Greeting({ name }) {
  return <p>こんにちは、{name} さん!</p>;
}
JSX

「props を使いたいなら、関数の引数にきちんと書く」が鉄則です。

2. 親側で渡し忘れて undefined になる

もう一つよくあるのが、「親が props を渡していない」パターンです。

例えば、子コンポーネントがこうなっているとします。

function Greeting({ name }) {
  return <p>こんにちは、{name} さん!</p>;
}
JSX

しかし親側がこう書いてしまうと問題です。

export default function Page() {
  return (
    <main>
      <Greeting />
    </main>
  );
}
JSX

name を渡していないので、nameundefined になり、
表示は「こんにちは、 さん!」のように空っぽになってしまいます。

正しくはこうです。

<Greeting name="太郎" />
JSX

もしくは、「name が渡されなかったときのデフォルト値」を用意する、という方法もあります。

function Greeting({ name = "ゲスト" }) {
  return <p>こんにちは、{name} さん!</p>;
}
JSX

これなら、親が name を渡さなくても「こんにちは、ゲスト さん!」と表示されます。

3. props 名と使う側の名前がズレている

親と子で「名前」を合わせるのも大事なポイントです。

例えば、親がこう書いているとします。

<Greeting username="太郎" />
JSX

でも子コンポーネントがこうなっていると、

function Greeting({ name }) {
  return <p>こんにちは、{name} さん!</p>;
}
JSX

usernamename で名前がずれているので、nameundefined になります。
ブラウザには「こんにちは、 さん!」のように出てしまいます。

この場合は、どちらかに合わせる必要があります。

親を直すか:

<Greeting name="太郎" />
JSX

子を直すか:

function Greeting({ username }) {
  return <p>こんにちは、{username} さん!</p>;
}
JSX

「親が渡す属性名」と「子が受け取る props 名」は、必ず一致させる必要があります。

4. 数値や式を “” で囲んでしまう

props に数値や式を渡すときは、{} を使います。
ここを " " で囲んでしまうミスもよくあります。

例えば、年齢を渡したいとします。

これは NG パターンです。

<UserInfo name="太郎" age="20" />
JSX

"20" は「文字列」になってしまいます。
もちろん、それでも動く場合は多いですが、「数値として計算したい」ときに問題になります。

正しくはこうです。

<UserInfo name="太郎" age={20} />
JSX

同じように、計算式も "" ではなく {} で囲います。

{/* NG */}
<Price value="1000 + 200" />

{/* OK */}
<Price value={1000 + 200} />
JSX

"" で囲むと「そのままの文字」になり、
{} で囲むと「JavaScript として評価された結果」になります。

props に「プログラム上の値」を渡したいときは、{} を使うと覚えておくと安全です。


まとめ(propsの感覚をつかむ)

props は、「親コンポーネントから子コンポーネントへデータを渡すための仕組み」であり、関数の引数のようなものです。
親は <Component propName="値" /> のように渡し、子は function Component(props)function Component({ propName }) で受け取り、{} の中に埋め込んで表示します。
データの流れは基本的に上から下(親 → 子)で、props を使うことで「同じコンポーネントを、違うデータで何度も使い回せる」ようになります。
よくあるミスは「props を引数に書き忘れる」「親が渡し忘れる」「名前がズレている」「数値や式を “” にしてしまう」などで、これらを意識して直せるようになると一気にエラーが減ります。

次のステップとしては、自分で

名前だけを変えて挨拶するコンポーネント
タイトルと本文を props で受け取る「カード」コンポーネント
金額と税率を受け取って税込み価格を出すコンポーネント

などを作ってみると、「propsでデータを渡す感覚」がかなりしっくり来るはずです。

タイトルとURLをコピーしました