こんにちは!Reactの世界へようこそ。チーフアーキテクトの私です。
新しい技術を学び始めるとき、画面が急に真っ白になったり、コンソールに赤文字でエラーが出たりすると、「うっ…」と心が折れそうになりますよね。でも、安心してください。今日お話しする「PropTypes(プロパティタイプス)」は、いわば「あなたのコードをそっと優しく守ってくれる、おせっかいで頼れるお母さんのような存在」です。
TypeScriptが全盛期のいま、「え、古いやり方なの?」と思われるかもしれませんが、ちょっと待ってください。TypeScriptを導入する前のプロジェクトや、サクッと動くプロトタイプを作るとき、そして何より「Reactのコンポーネントがどうやってデータをやり取りしているのか」の基本を体感する上で、PropTypesほど最高の教材はありません。
今日は、身近な例えを交えながら、一緒に楽しく紐解いていきましょう!
—
1. PropTypesってなに? お買い物の「注文票」で例えてみよう
Reactのコンポーネントというのは、いわば「オーダーメイドの家具屋さん」みたいなものです。
親コンポーネントが「こういう机を作って!」とデータを渡す(これが Props ですね)。職人である子コンポーネントが、そのデータを受け取って画面を描画します。
ここで想像してみてください。
お客さん(親)が、「高さ:100cm、色:茶色、引き出しの数:2つ」と注文票を書くはずが、うっかり「高さ:赤色!」なんて変な注文票を渡しちゃったらどうでしょう? 工場は大パニックですよね。
- 「数字を入れる場所に、色が指定されてるよ!」
- 「ないと困る『高さ』のデータが抜けてるよ!」
こういう「データのミスマッチ」を、実際にアプリが壊れる前に、こっそり開発者の耳元で「ねえ、ここ間違ってるよ」と教えてくれる仕組み。それが `PropTypes` です。
TypeScriptが「設計図の段階で絶対にミスをさせない堅い法律」だとすれば、PropTypesは「現場で作業しているときに、ベテランの先輩が『おいおい、それ型番違うぞ』と優しく突っ込んでくれるお守り」のようなものです。
—
2. 実際にコードを書いてみよう!
百聞は一見にしかず。まずは、一番シンプルな例を見てみましょう。
今回は、「プロフィールカード」を表示するコンポーネントを作ります。名前(文字列)と、年齢(数値)を受け取る設定にしてみましょう。
まずは、ReactでPropTypesを使うために、本体とは別にあるパッケージ(`prop-types`)をインポートする必要があります。
import React from ‘react’;
import PropTypes from ‘prop-types’; // これが今日の主役です!
// プロフィールを表示する子コンポーネント
function ProfileCard(props) {
return (
名前: {props.name}
年齢: {props.age}歳
);
}
// ★ここがポイント!コンポーネントに「こういうデータが欲しい!」とルールを定義します
ProfileCard.propTypes = {
name: PropTypes.string.isRequired, // nameは「文字列」で、かつ「絶対に必要(必須)」!
age: PropTypes.number, // ageは「数値」(必須ではない)
};
export default ProfileCard;
どうでしょう?見慣れない記述が出てきましたが、やっていることは単純です。
`ProfileCard.propTypes` という特別な箱を用意して、その中に「どのPropに、どんな型(データ形式)を期待するか」を書いてあげているだけなんです。
データの種類(バリデーション)のバリエーション
PropTypesには、JavaScriptのデータ型に対応したたくさんのチェック機能が用意されています。
- `PropTypes.string` : 文字列(”こんにちは”など)
- `PropTypes.number` : 数値(42など)
- `PropTypes.bool` : 真偽値(true または false)
- `PropTypes.array` : 配列([1, 2, 3]など)
- `PropTypes.object` : オブジェクト
- そして最後に `.isRequired` をつけると、「このデータが渡されてこなかったら、警告を出す!」という必須チェックになります。
—
3. 開発中に警告が出る瞬間を体験しよう
「でも、警告が出るって言われても、どうせ画面は動くんでしょ?」
そう思ったそこのあなた。その通り、JavaScriptは寛大なので、間違ったデータを渡しても画面自体は一応動こうとします。
しかし、ブラウザの「開発者ツール(Console)」を開いてみてください。そこには、PropTypesからの愛ある(そして少し厳しい)赤文字のメッセージが届いているはずです。
例えば、先ほどの `ProfileCard` に対して、親からうっかり年齢を文字列で渡しちゃったとします。
// 親コンポーネントでの呼び出しミス例
// ※本来は数値を渡すべきところを、文字列の “二十歳” を渡しちゃった!
このコードをブラウザで動かすと、コンソールにはこんな風に表示されます。
> Warning: Failed prop type: Invalid prop `age` of type `string` supplied to `ProfileCard`, expected `number`.
> (翻訳:おいおい、`ProfileCard`に渡された `age` は文字列だけどさ、こっちは数値(number)を期待してるんだよね……)
この警告の何が素晴らしいかと言うと、「バグがユーザーの目に触れる前に、開発者の段階で気づかせてくれる」という点です。大規模なアプリになればなるほど、この「早期発見」がどれだけ開発者の精神衛生を救うことか……!
—
4. デフォルト値を設定して、さらに優しくする
「データが渡されなかったとき用に、あらかじめデフォルトの値を決めておきたいな」という時もありますよね。そんなときは `defaultProps` の出番です。
function ProfileCard(props) {
return (
名前: {props.name}
年齢: {props.age}歳
);
}
// 型のルール(PropTypes)
ProfileCard.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
};
// データが渡されなかったときの「お留守番デフォルト値」
ProfileCard.defaultProps = {
age: 20, // ageが渡されなかったら、勝手に「20」を入れておく
};
こうしておけば、親コンポーネントがうっかり `age` を渡し忘れても、アプリがクラッシュすることなく、しれっと「20歳」として表示してくれます。なんて気が利く仕組みなんでしょう!
—
さいごに:完璧を目指さなくて大丈夫
ここまでPropTypesの魅力を熱く語ってきましたが、実務の現場では現在、より強力な型チェックができる「TypeScript」が主流になりつつあります。だから、「今からPropTypesをマスターしまくるぞ!」と意気込みすぎなくても大丈夫です。
ただ、Reactの歴史や、「コンポーネントが外からどんなデータをもらうべきか」というインターフェースの設計思想を学ぶ上で、PropTypesはこれ以上ないほどシンプルで優れた教材です。
「あ、コンポーネントを作る時は、どんなデータを受け取るべきかリストアップする癖をつけよう」
そう思っていただけたら、今日の私の話は大成功です。
エラーが出ても、「おっ、PropTypesの親切な先輩が教えてくれたな」とニヤリとしながら、一歩ずつ進んでいきましょう。あなたのReactライフを、チーフアーキテクトとしてずっと応援しています!

コメント