【入門編】 スプレッド演算子によるPropsの展開と型安全性 – React実践ガイド

こんにちは!Reactの学習、楽しく進めていますか?
画面をパーツごとに分けて組み立てられるようになってくると、「おっ、なんだかすごいアプリを作っているぞ!」というワクワク感が出てきますよね。

でも、そんな学習の途中で、多くの人が「うわっ…」とつまずく瞬間があります。それが、「Props(プロプス)の受け渡しと、その型付け」です。特に、親から子へデータを一括でバトンタッチする便利技「スプレッド演算子(`…props`)」を使おうとしたとき、TypeScriptの赤い波線(エラー)に怒られて途方に暮れてしまった経験はありませんか?

「全部まとめて渡したいだけなのに、なんでこんなに怒られるの……」
大丈夫ですよ!安心してください。今日は、このスプレッド演算子と型安全性の関係を、身近な例えを交えながら、一緒にやさしく解きほぐしていきましょう。

—

1. スプレッド演算子ってなぁに?(宅配便の「おまかせ段ボール」の例え)

Reactでは、親コンポーネントから子コンポーネントへ、データや設定を「Props」というお盆に載せて渡します。

例えば、ボタンを作る componente(コンポーネント)を考えてみましょう。ボタンには、文字(`label`)だけでなく、クリックされたときの処理(`onClick`)、さらにHTML本来が持っている属性(`disabled`や`type`など)もたくさん渡したいことがありますよね。

ひとつひとつ手渡ししていくと、コードがこんな風にパンパンになってしまいます。

// ひとつずつ手渡しする例(ちょっと大変…)

「あーー、めんどくさい!全部まとめてダンボールに詰めて、パッと送りつけたい!」
そんなときに使うのが、スプレッド演算子(`…`)です。

// スプレッド演算子で一括ポン!と渡す例
const buttonProps = {
label: “送信”,
onClick: handleClick,
disabled: isSending,
type: “submit”,
className: “btn-primary”,
};

return ;

この `…buttonProps` は、まるで「中身をぜーんぶバラして、宛先のコンポーネントに平らに並べて配置してね!」という魔法の呪文です。とってもスマートで、コードがスッキリしますよね。

—

2. でも、TypeScriptという「厳しい警備員」がやってくる

このスプレッド演算子は最高に便利なのですが、ここでTypeScriptという頼もしくも厳しい警備員が登場します。

「ちょっと待った!その段ボールの中に、何が入っているか証明書を見せてください!」

TypeScriptは、「どんなデータが来てもいいよ」という雑な状態を嫌います。「このPropsには、この型(種類)のものしか入れちゃダメ!」と厳しくチェックするのです。ここをサボると、後で「あれ?存在しないプロパティを読もうとしてアプリが真っ白になった!」というバグの原因になってしまいます。

—

3. 型安全を守りながらスプレッド渡す実践コード

では、どうすればこの「便利さ」と「型安全(エラーのない安心感)」を両立できるのでしょうか?
実際に、よくある「カスタムボタン」のコードを見てみましょう。

import React from ‘react’;

// ① 子コンポーネントが受け取るPropsの「設計図(型)」を作ります
// HTMLの標準的なボタンプラス、独自の「label」を受け取れるようにします
type MyButtonProps = React.ButtonHTMLAttributes & {
label: string;
};

// ② 子コンポーネントの定義
// 受け取ったたくさんのPropsを「…rest」という名前のリュックサックにまとめて入れます
export const MyButton: React.FC = ({ label, …rest }) => {
return (
// リュックサック(rest)を、そのまま本物の
);
};

コードのポイント解説

  • `React.ButtonHTMLAttributes`: これが魔法の合言葉です。「普通のHTMLのボタンが持っている属性(`disabled`, `onClick`, `type`, `id` などなど)をぜんぶ丸ごと借用します!」という意味になります。
  • `&`(交差型): 「HTMLのボタンの属性」に、私たちが独自に作りたい「`label: string`」をドッキングさせる合体パーツです。
  • `{ label, …rest }`: 届いた荷物から `label` だけを取り出し、残りの大量の属性(おまけの機能たち)を `rest` という名前の箱にひとまとめにしています。この命名は `props` でも構いませんが、`rest`(残りのもの、という意味)にしておくと、「あ、これは一括で流し込む用の残りカスだな」と一目でわかるので現場で好まれます。

—

4. やってはいけない!不要なPropsの混入を防ぐ注意点

ここで、実務でやりがちな「うっかりミス」についてお話しします。

スプレッド演算子は便利すぎるあまり、「本当は渡したくない余計なデータまで、子孫にズボラに流し込んでしまう」という副作用があります。

例えば、親コンポーネントで使っていた「ユーザーのパスワード情報」や「秘密のフラグ」が、うっかり `…props` の中に混ざっていたとしましょう。それがそのまま末端の `` タグや `

コメント

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