<CodeLearn/>
React レッスン3

Props

コンポーネントにデータを渡す仕組みを学ぼう

Propsとは?

Props(プロパティの略)は、親コンポーネントから子コンポーネントに データを渡すための仕組みです。HTMLの属性のように、コンポーネントにデータを渡すことができます。

Propsは読み取り専用です。子コンポーネントがPropsを直接変更することはできません。 これにより、データの流れが「親 → 子」という一方向になり、アプリの動作が予測しやすくなります。

Propsの基本的な使い方

// 方法1: propsオブジェクトで受け取る
function Greeting(props) {
  return <h1>こんにちは、{props.name}さん!</h1>;
}

// 方法2: 分割代入で受け取る(推奨)
function GreetingV2({ name }) {
  return <h1>こんにちは、{name}さん!</h1>;
}

// 複数のPropsを渡す
function UserCard({ name, age, email }) {
  return (
    <div className="card">
      <h2>{name}</h2>
      <p>年齢: {age}歳</p>
      <p>メール: {email}</p>
    </div>
  );
}

// 親コンポーネントからデータを渡す
function App() {
  return (
    <div>
      <Greeting name="太郎" />
      <Greeting name="花子" />
      <UserCard name="田中太郎" age={25} email="taro@example.com" />
    </div>
  );
}

文字列は "..." で、 数値やオブジェクトは {} で渡します。

さまざまな型のProps

Propsにはあらゆるデータ型を渡すことができます。

function Demo({
  text,        // 文字列
  count,       // 数値
  isActive,    // 真偽値
  items,       // 配列
  user,        // オブジェクト
  onClick,     // 関数
  children,    // 子要素
}) {
  return (
    <div>
      <p>{text}</p>
      <p>カウント: {count}</p>
      <p>状態: {isActive ? "有効" : "無効"}</p>
      <ul>
        {items.map((item, i) => (
          <li key={i}>{item}</li>
        ))}
      </ul>
      <p>ユーザー: {user.name}</p>
      <button onClick={onClick}>クリック</button>
      <div>{children}</div>
    </div>
  );
}

// 使い方
function App() {
  const handleClick = () => alert("クリック!");

  return (
    <Demo
      text="こんにちは"
      count={42}
      isActive={true}
      items={["りんご", "バナナ", "みかん"]}
      user={{ name: "太郎", age: 25 }}
      onClick={handleClick}
    >
      <p>これはchildren(子要素)です</p>
    </Demo>
  );
}

デフォルトProps

Propsが渡されなかった場合のデフォルト値を設定できます。

// 分割代入のデフォルト値(推奨)
function Button({ label = "ボタン", color = "blue", size = "medium" }) {
  const sizeMap = {
    small: "8px 12px",
    medium: "12px 24px",
    large: "16px 32px",
  };

  return (
    <button
      style={{
        backgroundColor: color,
        padding: sizeMap[size],
        color: "white",
        border: "none",
        borderRadius: "6px",
      }}
    >
      {label}
    </button>
  );
}

function App() {
  return (
    <div>
      {/* すべてデフォルト値を使用 */}
      <Button />

      {/* 一部だけカスタマイズ */}
      <Button label="送信" color="green" />

      {/* すべてカスタマイズ */}
      <Button label="削除" color="red" size="small" />
    </div>
  );
}

TypeScriptでのProps型定義

TypeScriptを使う場合、Propsに型を定義することで安全にデータを受け渡しできます。

// interfaceで型を定義
interface UserCardProps {
  name: string;
  age: number;
  email: string;
  isAdmin?: boolean;  // ?は省略可能(オプショナル)
}

function UserCard({ name, age, email, isAdmin = false }: UserCardProps) {
  return (
    <div className="card">
      <h2>{name} {isAdmin && "(管理者)"}</h2>
      <p>年齢: {age}歳</p>
      <p>メール: {email}</p>
    </div>
  );
}

// childrenを含む型
interface LayoutProps {
  title: string;
  children: React.ReactNode;
}

function Layout({ title, children }: LayoutProps) {
  return (
    <div>
      <h1>{title}</h1>
      <main>{children}</main>
    </div>
  );
}

Propsのスプレッド

オブジェクトのスプレッド構文を使って、Propsをまとめて渡すこともできます。

function Profile({ name, age, email }) {
  return (
    <div>
      <p>名前: {name}</p>
      <p>年齢: {age}</p>
      <p>メール: {email}</p>
    </div>
  );
}

function App() {
  const userData = {
    name: "田中太郎",
    age: 25,
    email: "taro@example.com",
  };

  // スプレッドでまとめて渡す
  return <Profile {...userData} />;

  // 上記は以下と同じ意味:
  // <Profile name="田中太郎" age={25} email="taro@example.com" />
}

まとめ

  • Propsは親から子へデータを渡す一方向のデータフロー
  • 分割代入で受け取るのが推奨パターン
  • デフォルト値で、省略可能なPropsを設定できる
  • TypeScriptのinterfaceで型安全にできる
  • スプレッド構文でオブジェクトをまとめて渡せる