前回、同じカードが3枚並びました。今回はここに1枚ずつ違う中身を入れます。
そのために外から渡す値がprops(プロパティ)です。コンポーネントは関数なので、propsはその引数にあたります。
// 渡す側(親)
<BirdCard name="シマエナガ" />
// 受け取る側(子)
function BirdCard(props) {
return <h2>{props.name}</h2>
}HTMLの属性を書く感覚で渡せますが、属性名は自分で決められます。
渡し方——文字列以外は波かっこ
<BirdCard
name="シマエナガ" {/* 文字列はそのまま */}
rare={3} {/* 数値は波かっこ */}
isRare={true} {/* 真偽値も波かっこ */}
bird={birdObject} {/* オブジェクトも波かっこ */}
/>波かっこは「ここからJavaScriptです」の合図でした。rare="3"と書くと文字列の'3'になってしまい、rare >= 3のような比較が思ったとおりに動きません。
受け取り方——分割代入が定番
受け取る側は、引数として受けとります。
function BirdCard(props) {
return (
<div>
<h2>{props.name}</h2>
<p>{props.memo}</p>
</div>
)
}props.が毎回付くのが読みにくいので、分割代入で取り出す書き方が定番です。
function BirdCard({ name, memo }) {
return (
<div>
<h2>{name}</h2>
<p>{memo}</p>
</div>
)
}やっていることは同じです。引数の波かっこは「オブジェクトから取り出す」の合図でした。Reactの記事はほぼこの書き方なので、こちらに慣れておくと読むのが楽になります。
propsは読み取り専用
子の中でpropsを書きかえてはいけません。
function BirdCard({ name }) {
name = 'スズメ' // ✕ やってはいけない
return <h2>{name}</h2>
}理由は2つあります。
- 画面が更新されない——Reactは「propsが書きかわった」を見ていません。表示は次に親が描き直したときの値に戻ります
- 追えなくなる——値は親から流れてくるはずなのに、途中で勝手に変わると、どこで変わったのか探せなくなります
Reactではデータは上から下へ一方通行に流れます。この決まりのおかげで「この値はどこから来たのか」を親へさかのぼるだけで追えます。
children——タグで挟んだ中身
開始タグと終了タグで挟んだ中身は、childrenという決まった名前のpropsで受け取れます。
function Panel({ children }) {
return <div className="rounded-2xl bg-white p-5 shadow-sm">{children}</div>
}<Panel>
<h2>シマエナガ</h2>
<p>雪のようにまっ白な小鳥。</p>
</Panel>「枠だけ用意して、中身は使う側が決める」というときに便利です。カード・モーダル・レイアウトなど、入れ物系の部品でよく使います。
カードをpropsで書きかえる
BirdCardが4つの値を受け取るようにします。
function BirdCard({ name, emoji, area, memo }) {
return (
<div className="flex gap-4 rounded-2xl bg-white p-5 shadow-sm">
<span className="text-4xl">{emoji}</span>
<div>
<div className="flex items-center gap-2">
<h2 className="font-bold text-slate-800">{name}</h2>
<span className="rounded-full bg-sky-100 px-2 py-0.5 text-xs text-sky-700">
{area}
</span>
</div>
<p className="mt-1 text-sm text-slate-600">{memo}</p>
</div>
</div>
)
}
export default BirdCard親からは、3羽ぶんの値を渡します。
<div className="mt-6 space-y-4">
<BirdCard
name="シマエナガ"
emoji="🐦"
area="北海道"
memo="雪のようにまっ白な小鳥。ふわふわの丸い体。"
/>
<BirdCard
name="スズメ"
emoji="🐤"
area="まちなか"
memo="いちばん身近な小鳥。ちゅんちゅん鳴いている。"
/>
<BirdCard
name="フクロウ"
emoji="🦉"
area="もり"
memo="夜に活動する。首がぐるりとよく回る。"
/>
</div>カードの見た目を直すときはBirdCard.jsxの1か所で済みます。3枚とも同時に変わります。これが部品にした効果です。
公式ドキュメントも見てみる
ja.react.dev外部サイトコンポーネントに props を渡す – React公式の「コンポーネントにpropsを渡す」。「propsを分割代入する」の節と、最後の「propsは時間とともに変化する」の節がこの回の要点そのものですこのレッスンのまとめ
- props=親から子へ渡す値。コンポーネントは関数なので、propsはその引数
- 文字列以外(数値・真偽値・オブジェクト)は波かっこで渡す
- 受け取りは分割代入
{ name, memo }が定番。既定値も書ける - propsは読み取り専用——子で書きかえない。変わる値はstateの担当
- タグで挟んだ中身は
childrenで受け取れる - 渡す名前と受け取る名前がズレると、エラーなしで空欄になる
次は、この3枚をデータの配列から自動で並べます。8羽ぶんのカードを手で書かずに済ませる回です。
