「同じボタンなのに、文字だけ変えたい…」 「カードのデザインは同じだけど、タイトルと内容を変えたい…」
Reactのコンポーネントを作ってみたものの、このような悩みを持ったことはありませんか?実は、propsを使えば、同じコンポーネントを異なる内容で表示できるんです。
今回は、Reactの重要な概念「props」の使い方を、実践的なコード例を交えながら解説していきます。この記事を読めば、コンポーネントを自在にカスタマイズできるようになり、Reactの真の力を実感できるはずです。
Reactのprops:コンポーネントをカスタマイズする方法を学ぼう
「同じボタンなのに、文字だけ変えたい…」 「カードのデザインは同じだけど、タイトルと内容を変えたい…」
Reactのコンポーネントを作ってみたものの、このような悩みを持ったことはありませんか?実は、propsを使えば、同じコンポーネントを異なる内容で表示できるんです。
今回は、Reactの重要な概念「props」の使い方を、実践的なコード例を交えながら解説していきます。この記事を読めば、コンポーネントを自在にカスタマイズできるようになり、Reactの真の力を実感できるはずです。
propsとは何か
propsは「properties(プロパティ)」の略で、コンポーネントに渡すデータのことです。HTMLの属性に似ていますが、より柔軟にデータを扱えます。
たとえば、従来のHTMLでは以下のようにボタンを書いていました:
<button type="button" class="primary">送信する</button>
<button type="button" class="secondary">キャンセル</button>
Reactでpropsを使うと、このように書けます:
<Button text="送信する" variant="primary" />
<Button text="キャンセル" variant="secondary" />
propsの基本的な使い方
propsの受け取り方
function Button(props) {
return (
<button className={`button ${props.variant}`}>
{props.text}
</button>
);
}
より一般的な書き方として、分割代入を使用します:
function Button({ text, variant }) {
return (
<button className={`button ${variant}`}>
{text}
</button>
);
}
デフォルト値の設定
propsが渡されなかった場合のデフォルト値を設定できます:
function Button({ text = 'クリック', variant = 'primary' }) {
return (
<button className={`button ${variant}`}>
{text}
</button>
);
}
実践的なpropsの活用例
汎用ボタンコンポーネント
const Button = ({ text = 'クリック', variant = 'primary', onClick, disabled = false }) => {
const baseStyle = 'px-4 py-2 rounded font-medium focus:outline-none transition-colors';
const variantStyles = {
primary: 'bg-blue-500 text-white hover:bg-blue-600',
secondary: 'bg-gray-500 text-white hover:bg-gray-600',
outline: 'border-2 border-blue-500 text-blue-500 hover:bg-blue-50'
};
return (
<button
className={`${baseStyle} ${variantStyles[variant]}`}
onClick={onClick}
disabled={disabled}
>
{text}
</button>
);
};
// 使用例を表示するためのデモコンポーネント
const ButtonDemo = () => {
return (
<div className="space-y-4">
<div className="space-x-4">
<Button text="送信する" />
<Button text="キャンセル" variant="secondary" />
<Button text="詳細を見る" variant="outline" />
</div>
<div className="space-x-4">
<Button disabled text="送信する" />
<Button disabled text="キャンセル" variant="secondary" />
</div>
</div>
);
};
export default ButtonDemo;
カードコンポーネント
続いて、カードコンポーネントも作ってみましょう:
const Card = ({ title, description, image, variant = 'default' }) => {
const baseStyle = 'rounded-lg overflow-hidden shadow-md';
const variantStyles = {
default: 'bg-white',
highlighted: 'bg-blue-50 border-2 border-blue-200'
};
return (
<div className={`${baseStyle} ${variantStyles[variant]}`}>
{image && (
<img
src={image}
alt={title}
className="w-full h-48 object-cover"
/>
)}
<div className="p-4">
<h3 className="text-xl font-bold mb-2">{title}</h3>
<p className="text-gray-600">{description}</p>
</div>
</div>
);
};
// 使用例を表示するためのデモコンポーネント
const CardDemo = () => {
return (
<div className="grid grid-cols-2 gap-4">
<Card
title="はじめてのReact"
description="Reactの基礎を学びましょう。コンポーネントとpropsについて解説します。"
/>
<Card
title="上級者向けReact"
description="パフォーマンスチューニングとベストプラクティスについて解説します。"
variant="highlighted"
/>
</div>
);
};
export default CardDemo;
よくある間違いと解決方法
1. propsの分割代入を忘れる
// ❌ 冗長な書き方
function Button(props) {
return <button>{props.text}</button>;
}
// ✅ 分割代入を使用した書き方
function Button({ text }) {
return <button>{text}</button>;
}
2. propsの直接変更
// ❌ propsを直接変更してはいけない
function Button({ text }) {
text = text.toUpperCase(); // ❌ エラー
return <button>{text}</button>;
}
// ✅ 新しい変数に代入して使用
function Button({ text }) {
const upperText = text.toUpperCase(); // OK
return <button>{upperText}</button>;
}
3. props.childrenの使い忘れ
// ❌ 柔軟性に欠ける実装
function Button({ text }) {
return <button>{text}</button>;
}
// ✅ childrenを使用した柔軟な実装
function Button({ children }) {
return <button>{children}</button>;
}
// 使用例
<Button>
<span>送信</span>
<img src="icon.png" alt="" />
</Button>
まとめ
propsを使うことで、コンポーネントを柔軟にカスタマイズできることがわかりました。重要なポイントを復習しましょう:
- propsはコンポーネントに渡すデータ
- 分割代入を使って簡潔に書ける
- デフォルト値を設定できる
- childrenで子要素を受け取れる
- propsは直接変更しない
次回は、コンポーネントの状態を管理する「useState」について学んでいきます。これを使えば、ユーザーの操作に応じて動的に変化するUIを作れるようになります。お楽しみに!