モダンJavaScriptの基礎から始める挫折しないためのReact入門 60日コース | Reactの基本 - DAY 17:Props実践

React 60日で身につけるReact
スポンサーリンク
スポンサーリンク
  1. DAY 17:Props実践 前半 ― 「一歩進んだProps」でコンポーネントをもっと柔軟にする
  2. オブジェクトProps ― 「まとまった情報を1つのPropsで渡す」
    1. なぜオブジェクトで渡すのか
  3. Array Props ― 「一覧データをコンポーネントに渡す」
    1. 配列を渡して、コンポーネント側で .map() する
  4. Function Props ― 「子コンポーネントから親の処理を呼び出す」
    1. なぜ関数をPropsとして渡すのか
  5. children ― 「中身を差し替えられるコンポーネント」を作る
    1. props.children という特別なProps
  6. コンポーネントの再利用 ― 「Props+children」で汎用部品を作る
    1. 「枠」と「中身」を分けて再利用性を高める
  7. DAY 17:Props実践 前半のまとめ
  8. DAY 17:Props実践 中盤 ― 「Propsで画面全体を組み立てる」感覚を身につける
  9. オブジェクトPropsを「意味のあるまとまり」として扱う
    1. レッスン情報オブジェクトをそのまま渡す
    2. オブジェクトPropsを分割代入で扱う
  10. Array Propsで「一覧表示コンポーネント」を育てる
    1. 一覧表示専用コンポーネントを作る
  11. Function Propsで「操作」をコンポーネントに渡す
    1. 子コンポーネントから親の処理を呼び出す
  12. childrenで「枠コンポーネント」を汎用化する
    1. Cardコンポーネントを「枠」として設計する
  13. コンポーネントの再利用 ― 「Props設計で汎用性を高める」
    1. 再利用を前提にしたProps設計
  14. DAY 17:Props実践 中盤のまとめ
  15. DAY 17:Props実践 後半 ― 「実務レベルに近いProps設計」を体感する
  16. オブジェクトProps ― 「意味のあるまとまり」をそのまま渡す設計
    1. レッスン情報オブジェクトを中心に据える
  17. Array Props ― 「一覧表示+再利用」をセットで考える
    1. レッスン一覧をArray Propsで渡す
  18. Function Props ― 「操作の入口」をコンポーネントに渡す
    1. 子コンポーネントから親の処理を呼び出す流れ
  19. children ― 「枠コンポーネント」で画面構造を整理する
    1. Cardコンポーネントを汎用的な枠として使う
  20. コンポーネントの再利用 ― 「Props設計で汎用性を意識する」
    1. 再利用を前提にしたコンポーネント群の設計
  21. DAY 17:Props実践 後半のまとめ
  22. DAY 17:Props実践 ミニ課題 ― プロフィールカードを作ってみる
  23. プロフィールカードのゴールイメージを決める
  24. オブジェクトProps ― プロフィール情報を1つのまとまりとして渡す
    1. プロフィールオブジェクトを定義する
    2. ProfileCardコンポーネントでオブジェクトPropsを受け取る
  25. Array Props ― スキル一覧を配列として渡す
    1. スキル一覧を表示するコンポーネントを作る
    2. ProfileCardの中でSkillListを使う
  26. Function Props ― 「フォローする」ボタンの動きを渡す
    1. フォロー処理を親コンポーネントに定義する
    2. ProfileCardでFunction Propsを使う
  27. children ― プロフィールカードを「枠」として再利用する
    1. Cardコンポーネントで「枠」を作る
    2. Cardの中にProfileCardを入れる
  28. コンポーネントの再利用 ― 複数プロフィールを表示してみる
    1. Array Props+再利用で「プロフィール一覧」を作る
  29. DAY 17:ミニ課題「プロフィールカード」のまとめ

DAY 17:Props実践 前半 ― 「一歩進んだProps」でコンポーネントをもっと柔軟にする

DAY 17では、DAY 16で学んだ基本的なProps(String / Number / Boolean)から一歩進んで、 より実践的な オブジェクトProps / Array Props / Function Props / children / コンポーネントの再利用 を扱っていきます。

ここから、コンポーネントは「ただ表示するだけの部品」から、 柔軟に組み替えられる“本物のUI部品” に近づいていきます。

オブジェクトProps ― 「まとまった情報を1つのPropsで渡す」

なぜオブジェクトで渡すのか

レッスン情報のように、複数の値がセットになっているものを扱うとき、 1つ1つをバラバラに渡すよりも、オブジェクトとしてまとめて渡すほうが読みやすくなることがあります。

まず、バラバラに渡す例を見てみます。

function LessonCard({ day, title, isImportant }) {
  return (
    <div>
      <h3>
        DAY {day}{title}
      </h3>
      <p>
        このレッスンは
        {isImportant ? "重要レッスンです。" : "通常レッスンです。"}
      </p>
    </div>
  );
}

function App() {
  return (
    <div>
      <LessonCard day={17} title="Props実践" isImportant={true} />
    </div>
  );
}
JSX

これでも問題なく動きますが、 「レッスン」という意味のまとまりが、Propsの列からは少し分かりにくいです。

そこで、オブジェクトPropsを使ってみます。

function LessonCard({ lesson }) {
  return (
    <div>
      <h3>
        DAY {lesson.day}{lesson.title}
      </h3>
      <p>
        このレッスンは
        {lesson.isImportant ? "重要レッスンです。" : "通常レッスンです。"}
      </p>
    </div>
  );
}

function App() {
  const lesson = {
    day: 17,
    title: "Props実践",
    isImportant: true,
  };

  return (
    <div>
      <LessonCard lesson={lesson} />
    </div>
  );
}
JSX

ここで起きていることを整理すると、

  1. 親コンポーネント App は、lesson というオブジェクトを持っています。
  2. <LessonCard lesson={lesson} /> として、オブジェクトを丸ごとPropsとして渡しています。
  3. 子コンポーネント LessonCard は、lesson.daylesson.titlelesson.isImportant として中身を使っています。

重要ポイント:

  • オブジェクトPropsは、「意味のあるまとまり」を1つのPropsとして渡したいときに有効です。
  • 「これはレッスン情報だ」「これはユーザー情報だ」といった意味が、コードから読み取りやすくなります。

Array Props ― 「一覧データをコンポーネントに渡す」

配列を渡して、コンポーネント側で .map() する

DAY 16では、親コンポーネント側で lessons.map(...) を使っていましたが、 今度は 配列そのものを子コンポーネントに渡して、子の中で .map() する 形を見てみます。

function LessonList({ lessons }) {
  return (
    <section>
      <h2>レッスン一覧</h2>
      <ul>
        {lessons.map((lesson) => (
          <li key={lesson.day}>
            DAY {lesson.day}{lesson.title}
          </li>
        ))}
      </ul>
    </section>
  );
}

function App() {
  const lessons = [
    { day: 16, title: "Props", isImportant: true },
    { day: 17, title: "Props実践", isImportant: true },
    { day: 18, title: "State", isImportant: true },
  ];

  return (
    <div>
      <h1>React入門 60日コース</h1>
      <LessonList lessons={lessons} />
    </div>
  );
}
JSX

ここで起きていることをステップで整理すると、

  1. 親コンポーネント App は、lessons という配列を持っています。
  2. <LessonList lessons={lessons} /> として、配列を丸ごとPropsとして渡しています。
  3. 子コンポーネント LessonList は、lessons.map(...) を使って一覧表示を行っています。

重要ポイント:

  • Array Propsは、「一覧表示を担当するコンポーネント」に配列を渡すときに使います。
  • 親は「データを持つ」、子は「一覧表示を担当する」という役割分担が明確になります。

Function Props ― 「子コンポーネントから親の処理を呼び出す」

なぜ関数をPropsとして渡すのか

ここまでのPropsは「表示のためのデータ」でしたが、 Reactでは 関数をPropsとして渡す ことも非常によくあります。

これは、

子コンポーネントから親コンポーネントの処理を呼び出す

ための仕組みです。

まず、シンプルな例を見てみます。

function LessonButton({ onClick, label }) {
  return <button onClick={onClick}>{label}</button>;
}

function App() {
  const handleStartLesson = () => {
    console.log("レッスンを開始します");
  };

  return (
    <div>
      <h1>React入門 60日コース</h1>
      <LessonButton onClick={handleStartLesson} label="DAY 17を開始" />
    </div>
  );
}
JSX

ここで起きていることをステップで整理すると、

  1. 親コンポーネント App は、handleStartLesson という関数を持っています。
  2. <LessonButton onClick={handleStartLesson} label="DAY 17を開始" /> として、関数をPropsとして渡しています。
  3. 子コンポーネント LessonButton は、onClick をボタンの onClick イベントにそのまま渡しています。
  4. ボタンがクリックされると、handleStartLesson が呼び出されます。

重要ポイント:

  • Function Propsは、「子コンポーネントから親の処理を呼び出す」ための橋渡しです。
  • 表示だけでなく、「動き」や「イベント処理」をコンポーネント間でつなぐために使われます。

children ― 「中身を差し替えられるコンポーネント」を作る

props.children という特別なProps

Reactには、特別なPropsとして children があります。 これは、コンポーネントの「タグの間に書かれた中身」を受け取るためのPropsです。

まず、childrenを使わない形を見てみます。

function Card() {
  return (
    <div className="card">
      <p>ここに何か表示します</p>
    </div>
  );
}

function App() {
  return (
    <div>
      <Card />
    </div>
  );
}
JSX

この Card は、中身が固定されています。 どこで使っても「ここに何か表示します」としか出せません。

そこで、childrenを使って中身を差し替えられるようにします。

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

function App() {
  return (
    <div>
      <Card>
        <h2>DAY 17:Props実践</h2>
        <p>オブジェクトProps・Array Props・Function Props・childrenを学びます。</p>
      </Card>

      <Card>
        <h2>お知らせ</h2>
        <p>次回はStateについて学びます。</p>
      </Card>
    </div>
  );
}
JSX

ここで起きていることをステップで整理すると、

  1. Card は、children というPropsを受け取っています。
  2. <Card> ... </Card> の「…」の部分が、children に入ります。
  3. Card は、{children} を表示することで、中身を自由に差し替えられる「枠」として機能します。

重要ポイント:

  • children は、「コンポーネントの中身を外から差し替えたいとき」に使う特別なPropsです。
  • Card のような「枠コンポーネント」を作るときに非常に便利です。

コンポーネントの再利用 ― 「Props+children」で汎用部品を作る

「枠」と「中身」を分けて再利用性を高める

ここまでの内容を組み合わせて、 再利用性の高いコンポーネント を作ってみます。

function Card({ title, children }) {
  return (
    <div className="card">
      <h2>{title}</h2>
      <div className="card-content">{children}</div>
    </div>
  );
}

function LessonList({ lessons }) {
  return (
    <ul>
      {lessons.map((lesson) => (
        <li key={lesson.day}>
          DAY {lesson.day}{lesson.title}
        </li>
      ))}
    </ul>
  );
}

function App() {
  const lessons = [
    { day: 16, title: "Props", isImportant: true },
    { day: 17, title: "Props実践", isImportant: true },
    { day: 18, title: "State", isImportant: true },
  ];

  const handleStartLesson = () => {
    console.log("レッスンを開始します");
  };

  return (
    <div>
      <h1>React入門 60日コース</h1>

      <Card title="レッスン一覧">
        <LessonList lessons={lessons} />
      </Card>

      <Card title="操作">
        <button onClick={handleStartLesson}>DAY 17を開始</button>
      </Card>
    </div>
  );
}

export default App;
JSX

このコードには、

  • オブジェクトProps(lessons の各要素)
  • Array Props(LessonList に渡される lessons
  • Function Props(handleStartLesson をボタンの onClick に渡す)
  • children(Card に渡される中身)
  • コンポーネントの再利用(Card を「レッスン一覧」と「操作」の2箇所で使い回し)

がすべて含まれています。

重要ポイント:

  • Propsとchildrenを組み合わせることで、「枠」と「中身」を分けた汎用コンポーネントを作れます。
  • 再利用性の高いコンポーネントは、アプリ全体の保守性を大きく高めます。

DAY 17:Props実践 前半のまとめ

この前半では、

  • オブジェクトPropsで「意味のあるまとまり」を1つのPropsとして渡す考え方
  • Array Propsで「一覧表示を担当するコンポーネント」に配列を渡すパターン
  • Function Propsで「子コンポーネントから親の処理を呼び出す」仕組み
  • children を使って「中身を差し替えられる枠コンポーネント」を作る方法
  • Props+childrenを組み合わせて、再利用性の高いコンポーネントを設計する流れ

をステップバイステップで確認しました。

中盤・後半では、 ここで学んだ実践的なPropsの使い方をさらに発展させて、 「イベントとState」と組み合わせながら、よりインタラクティブなUIへと進んでいきます。


DAY 17:Props実践 中盤 ― 「Propsで画面全体を組み立てる」感覚を身につける

DAY 17の中盤では、前半で触れた

  • オブジェクトProps
  • Array Props
  • Function Props
  • children
  • コンポーネントの再利用

を、もう一歩踏み込んで「画面全体をPropsで設計する」イメージをつかんでいきます。 ここでは、ダッシュボード画面を題材にして、Propsを使ってUIを組み立てる流れをステップバイステップで確認していきます。

オブジェクトPropsを「意味のあるまとまり」として扱う

レッスン情報オブジェクトをそのまま渡す

まず、「レッスンカード」をオブジェクトPropsで扱う例をもう少し実践的に見ていきます。

function LessonCard({ lesson }) {
  return (
    <div className="lesson-card">
      <h3>
        DAY {lesson.day}{lesson.title}
      </h3>
      <p>
        このレッスンは
        {lesson.isImportant ? "重要レッスンです。" : "通常レッスンです。"}
      </p>
    </div>
  );
}
JSX

ここで lesson は、

{
  day: 17,
  title: "Props実践",
  isImportant: true,
}
JavaScript

のようなオブジェクトを想定しています。

親コンポーネント側では、次のように使います。

function App() {
  const lesson = {
    day: 17,
    title: "Props実践",
    isImportant: true,
  };

  return (
    <div>
      <LessonCard lesson={lesson} />
    </div>
  );
}
JSX

ここで起きていることを整理すると、

  1. 親コンポーネント App は、lesson というオブジェクトを持っています。
  2. <LessonCard lesson={lesson} /> として、オブジェクトを丸ごとPropsとして渡しています。
  3. 子コンポーネント LessonCard は、lesson.daylesson.titlelesson.isImportant として中身を使っています。

オブジェクトPropsを分割代入で扱う

さらに読みやすくするために、オブジェクトPropsを分割代入で扱うこともできます。

function LessonCard({ lesson: { day, title, isImportant } }) {
  return (
    <div className="lesson-card">
      <h3>
        DAY {day}{title}
      </h3>
      <p>
        このレッスンは
        {isImportant ? "重要レッスンです。" : "通常レッスンです。"}
      </p>
    </div>
  );
}
JSX

重要ポイント:

  • オブジェクトPropsは、「意味のあるまとまり」を1つのPropsとして渡したいときに有効です。
  • 分割代入を組み合わせることで、コードを短く・読みやすくできます。

Array Propsで「一覧表示コンポーネント」を育てる

一覧表示専用コンポーネントを作る

次に、レッスン一覧を表示するコンポーネントを、Array Propsで設計してみます。

function LessonList({ lessons }) {
  return (
    <section className="lesson-list">
      <h2>レッスン一覧</h2>
      <ul>
        {lessons.map((lesson) => (
          <li key={lesson.day}>
            DAY {lesson.day}{lesson.title}
            {lesson.isImportant && <span>(重要)</span>}
          </li>
        ))}
      </ul>
    </section>
  );
}
JSX

親コンポーネント側では、次のように使います。

function App() {
  const lessons = [
    { day: 16, title: "Props", isImportant: true },
    { day: 17, title: "Props実践", isImportant: true },
    { day: 18, title: "State", isImportant: true },
  ];

  return (
    <div>
      <LessonList lessons={lessons} />
    </div>
  );
}
JSX

ここで起きていることをステップで整理すると、

  1. 親コンポーネント App は、lessons という配列を持っています。
  2. <LessonList lessons={lessons} /> として、配列を丸ごとPropsとして渡しています。
  3. 子コンポーネント LessonList は、lessons.map(...) を使って一覧表示を行っています。

重要ポイント:

  • Array Propsは、「一覧表示を担当するコンポーネント」に配列を渡すときに使います。
  • 親は「データを持つ」、子は「一覧表示を担当する」という役割分担が明確になります。

Function Propsで「操作」をコンポーネントに渡す

子コンポーネントから親の処理を呼び出す

次に、Function Propsを使って「操作」をコンポーネントに渡す例を見ていきます。

function LessonActionButton({ onStart, day }) {
  return (
    <button onClick={() => onStart(day)}>
      DAY {day} を開始
    </button>
  );
}
JSX

親コンポーネント側では、次のように使います。

function App() {
  const handleStartLesson = (day) => {
    console.log(`DAY ${day} のレッスンを開始します`);
  };

  return (
    <div>
      <LessonActionButton onStart={handleStartLesson} day={17} />
      <LessonActionButton onStart={handleStartLesson} day={18} />
    </div>
  );
}
JSX

ここで起きていることをステップで整理すると、

  1. 親コンポーネント App は、handleStartLesson という関数を持っています。
  2. <LessonActionButton onStart={handleStartLesson} day={17} /> として、関数と数値をPropsとして渡しています。
  3. 子コンポーネント LessonActionButton は、onStart(day) をボタンのクリック時に呼び出しています。
  4. ボタンがクリックされると、親コンポーネントの handleStartLesson が呼び出されます。

重要ポイント:

  • Function Propsは、「子コンポーネントから親の処理を呼び出す」ための橋渡しです。
  • 表示だけでなく、「動き」や「イベント処理」をコンポーネント間でつなぐために使われます。

childrenで「枠コンポーネント」を汎用化する

Cardコンポーネントを「枠」として設計する

次に、children を使って「枠コンポーネント」を汎用化する例を見ていきます。

function Card({ title, children }) {
  return (
    <div className="card">
      <h2>{title}</h2>
      <div className="card-content">
        {children}
      </div>
    </div>
  );
}
JSX

親コンポーネント側では、次のように使います。

function App() {
  const lessons = [
    { day: 16, title: "Props", isImportant: true },
    { day: 17, title: "Props実践", isImportant: true },
    { day: 18, title: "State", isImportant: true },
  ];

  const handleStartLesson = (day) => {
    console.log(`DAY ${day} のレッスンを開始します`);
  };

  return (
    <div>
      <Card title="レッスン一覧">
        <LessonList lessons={lessons} />
      </Card>

      <Card title="操作">
        <LessonActionButton onStart={handleStartLesson} day={17} />
      </Card>
    </div>
  );
}
JSX

ここで起きていることをステップで整理すると、

  1. Card は、titlechildren をPropsとして受け取っています。
  2. <Card> ... </Card> の「…」の部分が、children に入ります。
  3. Card は、title を見出しとして表示し、children を中身として表示する「枠」として機能します。
  4. 同じ Card コンポーネントを、「レッスン一覧」と「操作」の2つの用途で再利用しています。

重要ポイント:

  • children は、「コンポーネントの中身を外から差し替えたいとき」に使う特別なPropsです。
  • 「枠」と「中身」を分けることで、再利用性の高いコンポーネントを作れます。

コンポーネントの再利用 ― 「Props設計で汎用性を高める」

再利用を前提にしたProps設計

ここまでの内容をまとめて、 再利用性の高いコンポーネント群 を1つの画面として組み立ててみます。

function LessonCard({ lesson }) {
  return (
    <div className="lesson-card">
      <h3>
        DAY {lesson.day}{lesson.title}
      </h3>
      <p>
        このレッスンは
        {lesson.isImportant ? "重要レッスンです。" : "通常レッスンです。"}
      </p>
    </div>
  );
}

function LessonList({ lessons }) {
  return (
    <section className="lesson-list">
      <ul>
        {lessons.map((lesson) => (
          <li key={lesson.day}>
            <LessonCard lesson={lesson} />
          </li>
        ))}
      </ul>
    </section>
  );
}

function LessonActionButton({ onStart, day }) {
  return (
    <button onClick={() => onStart(day)}>
      DAY {day} を開始
    </button>
  );
}

function Card({ title, children }) {
  return (
    <div className="card">
      <h2>{title}</h2>
      <div className="card-content">
        {children}
      </div>
    </div>
  );
}

function App() {
  const lessons = [
    { day: 16, title: "Props", isImportant: true },
    { day: 17, title: "Props実践", isImportant: true },
    { day: 18, title: "State", isImportant: true },
  ];

  const handleStartLesson = (day) => {
    console.log(`DAY ${day} のレッスンを開始します`);
  };

  return (
    <div>
      <h1>React入門 60日コース ダッシュボード</h1>

      <Card title="レッスン一覧">
        <LessonList lessons={lessons} />
      </Card>

      <Card title="操作">
        <LessonActionButton onStart={handleStartLesson} day={17} />
      </Card>
    </div>
  );
}

export default App;
JSX

このコードには、

  • オブジェクトProps(lesson
  • Array Props(lessons
  • Function Props(onStart
  • children(Card に渡される中身)
  • コンポーネントの再利用(CardLessonCardLessonListLessonActionButton の複数箇所での利用)

がすべて含まれています。

重要ポイント:

  • Props設計は「このコンポーネントは何を外から変えられるべきか?」を考えることから始まります。
  • オブジェクト・配列・関数・childrenを組み合わせることで、画面全体を柔軟に組み立てられるようになります。

DAY 17:Props実践 中盤のまとめ

この中盤では、

  • オブジェクトPropsを使って「意味のあるまとまり」を1つのPropsとして渡す感覚を深めたこと
  • Array Propsで「一覧表示コンポーネント」を育て、親と子の役割分担を明確にしたこと
  • Function Propsで「子コンポーネントから親の処理を呼び出す」流れを具体的な例で確認したこと
  • children を使って「枠コンポーネント」を汎用化し、同じ枠を複数の用途で再利用できることを体感したこと
  • これらを組み合わせて、ダッシュボード画面全体をPropsで設計するイメージを持てたこと

が大きなポイントになります。

後半では、 ここで作ったようなコンポーネント群をさらに発展させて、 Stateやイベントと組み合わせながら、よりインタラクティブなUIへと進んでいきます。


DAY 17:Props実践 後半 ― 「実務レベルに近いProps設計」を体感する

DAY 17の後半では、これまで扱ってきた

  • オブジェクトProps
  • Array Props
  • Function Props
  • children
  • コンポーネントの再利用

を、「実務レベルに近い形」でまとめて使うことを目標にします。 単なるサンプルコードではなく、小さな“本物っぽい画面”をPropsだけで組み立てる感覚をつかんでいきます。

ここでは「学習コースのダッシュボード」を題材に、 Props設計をステップバイステップで深掘りしていきます。

オブジェクトProps ― 「意味のあるまとまり」をそのまま渡す設計

レッスン情報オブジェクトを中心に据える

まず、レッスン情報を「1つのオブジェクト」として扱うところから始めます。

const lesson17 = {
  day: 17,
  title: "Props実践",
  isImportant: true,
  description: "オブジェクトProps・Array Props・Function Props・children・再利用を学びます。",
};
JSX

このようなオブジェクトを中心に据えて、コンポーネントに渡していきます。

function LessonCard({ lesson }) {
  return (
    <div className="lesson-card">
      <h3>
        DAY {lesson.day}{lesson.title}
        {lesson.isImportant && <span className="badge">重要</span>}
      </h3>
      <p>{lesson.description}</p>
    </div>
  );
}
JSX

ここで起きていることを整理すると、

  1. lesson は「レッスンに関する情報のまとまり」です。
  2. LessonCard は、そのまとまりを丸ごと受け取り、必要なプロパティだけを使って表示しています。
  3. 「これはレッスン情報だ」という意味が、lesson という名前から明確に伝わります。

重要ポイント:

  • オブジェクトPropsは、「意味のあるまとまり」をそのまま渡すための道具です。
  • プロパティが増えても、lesson という1つのPropsで渡せるため、呼び出し側のコードがスッキリします。

Array Props ― 「一覧表示+再利用」をセットで考える

レッスン一覧をArray Propsで渡す

次に、複数のレッスンを配列として扱い、それを一覧表示コンポーネントに渡します。

function LessonList({ lessons }) {
  return (
    <section className="lesson-list">
      <ul>
        {lessons.map((lesson) => (
          <li key={lesson.day}>
            <LessonCard lesson={lesson} />
          </li>
        ))}
      </ul>
    </section>
  );
}
JSX

親コンポーネント側では、次のように使います。

function App() {
  const lessons = [
    {
      day: 16,
      title: "Props基礎",
      isImportant: true,
      description: "Propsの基本的な使い方を学びます。",
    },
    {
      day: 17,
      title: "Props実践",
      isImportant: true,
      description: "オブジェクト・配列・関数・childrenを使った実践的なPropsを学びます。",
    },
    {
      day: 18,
      title: "State入門",
      isImportant: true,
      description: "コンポーネントの内部状態(State)について学びます。",
    },
  ];

  return (
    <div>
      <LessonList lessons={lessons} />
    </div>
  );
}
JSX

ここで起きていることをステップで整理すると、

  1. 親コンポーネント App は、lessons という配列を持っています。
  2. <LessonList lessons={lessons} /> として、配列を丸ごとPropsとして渡しています。
  3. LessonList は、lessons.map(...) を使って、各要素を LessonCard に渡しています。
  4. LessonCard は、オブジェクトPropsとして lesson を受け取り、表示を担当しています。

重要ポイント:

  • Array Propsは、「一覧表示を担当するコンポーネント」に配列を渡すための基本パターンです。
  • オブジェクトPropsと組み合わせることで、「一覧+カード」というよくあるUI構造を自然に表現できます。

Function Props ― 「操作の入口」をコンポーネントに渡す

子コンポーネントから親の処理を呼び出す流れ

次に、Function Propsを使って「操作の入口」をコンポーネントに渡します。

x

function LessonActionButton({ lesson, onStart }) {
  return (
    <button onClick={() => onStart(lesson)}>
      DAY {lesson.day} を開始
    </button>
  );
}
JSX

親コンポーネント側では、次のように使います。

function App() {
  const lessons = [/* さきほどの配列と同じ */];

  const handleStartLesson = (lesson) => {
    console.log(`DAY ${lesson.day}${lesson.title}」を開始します`);
  };

  return (
    <div>
      <LessonList lessons={lessons} />

      <LessonActionButton
        lesson={lessons[1]} // DAY 17
        onStart={handleStartLesson}
      />
    </div>
  );
}
JSX

ここで起きていることをステップで整理すると、

  1. 親コンポーネント App は、handleStartLesson という関数を持っています。
  2. <LessonActionButton lesson={lessons[1]} onStart={handleStartLesson} /> として、レッスン情報と関数をPropsとして渡しています。
  3. 子コンポーネント LessonActionButton は、ボタンがクリックされたときに onStart(lesson) を呼び出します。
  4. 結果として、親コンポーネントの handleStartLesson が呼び出され、レッスン情報を受け取ります。

重要ポイント:

  • Function Propsは、「子コンポーネントから親の処理を呼び出す」ための橋渡しです。
  • オブジェクトPropsと組み合わせることで、「どのレッスンを開始するか」といった情報も一緒に渡せます。

children ― 「枠コンポーネント」で画面構造を整理する

Cardコンポーネントを汎用的な枠として使う

次に、children を使って「枠コンポーネント」を設計します。

function Card({ title, children }) {
  return (
    <div className="card">
      <h2>{title}</h2>
      <div className="card-content">
        {children}
      </div>
    </div>
  );
}
JSX

この Card は、「タイトル付きの枠」を表現する汎用コンポーネントです。 中身は children として外から差し込めるようになっています。

親コンポーネント側では、次のように使います。

function App() {
  const lessons = [/* さきほどの配列と同じ */];

  const handleStartLesson = (lesson) => {
    console.log(`DAY ${lesson.day}${lesson.title}」を開始します`);
  };

  return (
    <div>
      <h1>React入門 60日コース ダッシュボード</h1>

      <Card title="レッスン一覧">
        <LessonList lessons={lessons} />
      </Card>

      <Card title="操作">
        <LessonActionButton
          lesson={lessons[1]} // DAY 17
          onStart={handleStartLesson}
        />
      </Card>
    </div>
  );
}
JSX

ここで起きていることをステップで整理すると、

  1. Card は、「タイトル+中身」という枠を提供するコンポーネントです。
  2. title Propsで見出しを変えられます。
  3. children Propsで中身を自由に差し替えられます。
  4. 同じ Card コンポーネントを、「レッスン一覧」と「操作」の2つの用途で再利用しています。

重要ポイント:

  • children は、「中身を差し替えられる枠コンポーネント」を作るための特別なPropsです。
  • 枠と中身を分けることで、画面構造を整理しやすくなり、再利用性も高まります。

コンポーネントの再利用 ― 「Props設計で汎用性を意識する」

再利用を前提にしたコンポーネント群の設計

ここまでの要素をすべて組み合わせて、 再利用性の高いコンポーネント群 を1つの画面として完成させてみます。

function LessonCard({ lesson }) {
  return (
    <div className="lesson-card">
      <h3>
        DAY {lesson.day}{lesson.title}
        {lesson.isImportant && <span className="badge">重要</span>}
      </h3>
      <p>{lesson.description}</p>
    </div>
  );
}

function LessonList({ lessons }) {
  return (
    <section className="lesson-list">
      <ul>
        {lessons.map((lesson) => (
          <li key={lesson.day}>
            <LessonCard lesson={lesson} />
          </li>
        ))}
      </ul>
    </section>
  );
}

function LessonActionButton({ lesson, onStart }) {
  return (
    <button onClick={() => onStart(lesson)}>
      DAY {lesson.day} を開始
    </button>
  );
}

function Card({ title, children }) {
  return (
    <div className="card">
      <h2>{title}</h2>
      <div className="card-content">
        {children}
      </div>
    </div>
  );
}

function App() {
  const lessons = [
    {
      day: 16,
      title: "Props基礎",
      isImportant: true,
      description: "Propsの基本的な使い方を学びます。",
    },
    {
      day: 17,
      title: "Props実践",
      isImportant: true,
      description: "オブジェクト・配列・関数・childrenを使った実践的なPropsを学びます。",
    },
    {
      day: 18,
      title: "State入門",
      isImportant: true,
      description: "コンポーネントの内部状態(State)について学びます。",
    },
  ];

  const handleStartLesson = (lesson) => {
    console.log(`DAY ${lesson.day}${lesson.title}」を開始します`);
  };

  return (
    <div>
      <h1>React入門 60日コース ダッシュボード</h1>

      <Card title="レッスン一覧">
        <LessonList lessons={lessons} />
      </Card>

      <Card title="操作">
        <LessonActionButton
          lesson={lessons[1]} // DAY 17
          onStart={handleStartLesson}
        />
      </Card>
    </div>
  );
}

export default App;
JSX

このコードには、

  • オブジェクトPropslesson
  • Array Propslessons
  • Function PropsonStart
  • childrenCard に渡される中身
  • コンポーネントの再利用LessonCardLessonListLessonActionButtonCard の複数箇所での利用

がすべて含まれています。

重要ポイント:

  • 再利用性の高いコンポーネントは、「何を外から変えられるべきか?」を意識してPropsを設計しています。
  • オブジェクト・配列・関数・childrenを組み合わせることで、画面全体を柔軟に組み立てられるようになります。

DAY 17:Props実践 後半のまとめ

この後半では、

  • オブジェクトPropsを使って「意味のあるまとまり」をそのまま渡す設計を確認したこと
  • Array Propsで「一覧+カード」というよくあるUI構造を自然に表現できることを体感したこと
  • Function Propsで「子コンポーネントから親の処理を呼び出す」流れを、レッスン開始ボタンの例で具体的に理解したこと
  • children を使って「枠コンポーネント」を汎用化し、同じ枠を複数の用途で再利用できることを確認したこと
  • これらを組み合わせて、学習コースのダッシュボード画面をPropsだけで組み立てるイメージを持てたこと

が大きなポイントになります。

ここまで進んだ読者のみなさんは、 すでに「Propsを使って画面全体を設計する」というReactの重要な感覚を身につけています。 次のDAYからは、このPropsと対になる State(コンポーネント自身が持つ状態) に進み、 「動きのあるUI」「ユーザー操作に応じて変化する画面」を作っていくことになります。


DAY 17:Props実践 ミニ課題 ― プロフィールカードを作ってみる

このミニ課題では、DAY 17で学んだ

  • オブジェクトProps
  • Array Props
  • Function Props
  • children
  • コンポーネントの再利用

を使って、プロフィールカードを作っていきます。 小さなコンポーネントですが、実務でもよく使われるパターンがぎゅっと詰まった題材ですので、 ステップバイステップでじっくり確認していきます。

プロフィールカードのゴールイメージを決める

まず、「どんなプロフィールカードを作るか」をざっくり決めます。

  • 名前
  • 職業(肩書き)
  • 自己紹介文
  • スキル一覧
  • 「フォローする」ボタン

を表示するカードを想定します。

画面イメージとしては、次のような感じです。

  • 上部に名前と肩書き
  • 中段に自己紹介文
  • 下部にスキル一覧
  • 一番下に「フォローする」ボタン

この構成を、ReactコンポーネントとPropsで組み立てていきます。

オブジェクトProps ― プロフィール情報を1つのまとまりとして渡す

プロフィールオブジェクトを定義する

まず、プロフィール情報をオブジェクトとして定義します。

const profile = {
  name: "受講者A",
  title: "React学習中エンジニア",
  bio: "60日コースでReactを集中学習しています。フロントエンドを軸にスキルアップ中です。",
  skills: ["JavaScript", "React", "HTML", "CSS"],
};
JSX

この profile オブジェクトを、プロフィールカードコンポーネントに渡します。

ProfileCardコンポーネントでオブジェクトPropsを受け取る

function ProfileCard({ profile }) {
  return (
    <div className="profile-card">
      <h2>{profile.name}</h2>
      <h3>{profile.title}</h3>
      <p>{profile.bio}</p>
    </div>
  );
}
JSX

ここで起きていることを整理すると、

  1. profile は「プロフィール情報のまとまり」です。
  2. ProfileCard は、そのまとまりを丸ごと受け取り、nametitlebio を表示しています。
  3. 「これはプロフィール情報だ」という意味が、profile という名前から明確に伝わります。

重要ポイント:

  • オブジェクトPropsは、「意味のあるまとまり」を1つのPropsとして渡したいときに有効です。
  • プロパティが増えても、呼び出し側は <ProfileCard profile={profile} /> のようにシンプルに書けます。

Array Props ― スキル一覧を配列として渡す

スキル一覧を表示するコンポーネントを作る

次に、プロフィールのスキル一覧を表示するコンポーネントを作ります。

function SkillList({ skills }) {
  return (
    <ul className="skill-list">
      {skills.map((skill) => (
        <li key={skill}>{skill}</li>
      ))}
    </ul>
  );
}
JSX

ここで skills は、["JavaScript", "React", "HTML", "CSS"] のような配列を想定しています。

ProfileCardの中でSkillListを使う

function ProfileCard({ profile }) {
  return (
    <div className="profile-card">
      <h2>{profile.name}</h2>
      <h3>{profile.title}</h3>
      <p>{profile.bio}</p>

      <h4>スキル</h4>
      <SkillList skills={profile.skills} />
    </div>
  );
}
JSX

ここで起きていることをステップで整理すると、

  1. profile.skills は、スキル名の配列です。
  2. <SkillList skills={profile.skills} /> として、配列をArray Propsとして渡しています。
  3. SkillList は、skills.map(...) を使って一覧表示を行っています。

重要ポイント:

  • Array Propsは、「一覧表示を担当するコンポーネント」に配列を渡すときに使います。
  • プロフィールカードの中に「スキル一覧」という小さな一覧コンポーネントを組み込むことで、構造が整理されます。

Function Props ― 「フォローする」ボタンの動きを渡す

フォロー処理を親コンポーネントに定義する

次に、「フォローする」ボタンの動きをFunction Propsで渡します。

function App() {
  const profile = {
    name: "受講者A",
    title: "React学習中エンジニア",
    bio: "60日コースでReactを集中学習しています。フロントエンドを軸にスキルアップ中です。",
    skills: ["JavaScript", "React", "HTML", "CSS"],
  };

  const handleFollow = (profile) => {
    console.log(`${profile.name} さんをフォローしました`);
  };

  return (
    <div>
      <ProfileCard profile={profile} onFollow={handleFollow} />
    </div>
  );
}
JSX

ここで、

  • handleFollow は「フォローする」処理を担当する関数です。
  • ProfileCardonFollow という名前でFunction Propsとして渡しています。

ProfileCardでFunction Propsを使う

function ProfileCard({ profile, onFollow }) {
  return (
    <div className="profile-card">
      <h2>{profile.name}</h2>
      <h3>{profile.title}</h3>
      <p>{profile.bio}</p>

      <h4>スキル</h4>
      <SkillList skills={profile.skills} />

      <button onClick={() => onFollow(profile)}>
        フォローする
      </button>
    </div>
  );
}
JSX

ここで起きていることをステップで整理すると、

  1. ProfileCard は、onFollow というFunction Propsを受け取っています。
  2. ボタンの onClick イベントで onFollow(profile) を呼び出しています。
  3. 結果として、親コンポーネントの handleFollow が呼び出され、profile オブジェクトを受け取ります。

重要ポイント:

  • Function Propsは、「子コンポーネントから親の処理を呼び出す」ための橋渡しです。
  • プロフィールカードは「見た目」と「ボタンの配置」を担当し、フォロー処理の中身は親コンポーネントに任せる設計になります。

children ― プロフィールカードを「枠」として再利用する

Cardコンポーネントで「枠」を作る

次に、children を使って「枠コンポーネント」を作り、プロフィールカードをその中に入れてみます。

function Card({ title, children }) {
  return (
    <div className="card">
      <h2>{title}</h2>
      <div className="card-content">
        {children}
      </div>
    </div>
  );
}
JSX

この Card は、「タイトル付きの枠」を表現する汎用コンポーネントです。

Cardの中にProfileCardを入れる

function App() {
  const profile = {
    name: "受講者A",
    title: "React学習中エンジニア",
    bio: "60日コースでReactを集中学習しています。フロントエンドを軸にスキルアップ中です。",
    skills: ["JavaScript", "React", "HTML", "CSS"],
  };

  const handleFollow = (profile) => {
    console.log(`${profile.name} さんをフォローしました`);
  };

  return (
    <div>
      <Card title="プロフィール">
        <ProfileCard profile={profile} onFollow={handleFollow} />
      </Card>

      <Card title="お知らせ">
        <p>次回はStateについて学びます。</p>
      </Card>
    </div>
  );
}
JSX

ここで起きていることをステップで整理すると、

  1. Card は、titlechildren をPropsとして受け取っています。
  2. <Card> ... </Card> の「…」の部分が、children に入ります。
  3. 同じ Card コンポーネントを、「プロフィール」と「お知らせ」の2つの用途で再利用しています。

重要ポイント:

  • children は、「中身を差し替えられる枠コンポーネント」を作るための特別なPropsです。
  • プロフィールカードも、Card の中に入れることで、画面全体の構造が整理されます。

コンポーネントの再利用 ― 複数プロフィールを表示してみる

Array Props+再利用で「プロフィール一覧」を作る

最後に、プロフィールカードを複数表示する「プロフィール一覧」を作ってみます。

function ProfileList({ profiles, onFollow }) {
  return (
    <div className="profile-list">
      {profiles.map((profile) => (
        <Card key={profile.name} title="プロフィール">
          <ProfileCard profile={profile} onFollow={onFollow} />
        </Card>
      ))}
    </div>
  );
}
JSX

親コンポーネント側では、次のように使います。

function App() {
  const profiles = [
    {
      name: "受講者A",
      title: "React学習中エンジニア",
      bio: "60日コースでReactを集中学習しています。",
      skills: ["JavaScript", "React"],
    },
    {
      name: "受講者B",
      title: "バックエンドエンジニア",
      bio: "フロントも触り始めました。",
      skills: ["Node.js", "Express"],
    },
  ];

  const handleFollow = (profile) => {
    console.log(`${profile.name} さんをフォローしました`);
  };

  return (
    <div>
      <h1>プロフィール一覧</h1>
      <ProfileList profiles={profiles} onFollow={handleFollow} />
    </div>
  );
}

export default App;
JSX

ここで起きていることをステップで整理すると、

  1. profiles は、プロフィールオブジェクトの配列です。
  2. <ProfileList profiles={profiles} onFollow={handleFollow} /> として、Array PropsとFunction Propsを渡しています。
  3. ProfileList は、profiles.map(...) を使って、各プロフィールに対して ProfileCard を表示しています。
  4. ProfileCard は、オブジェクトPropsとして profile を受け取り、表示と「フォローする」ボタンを担当しています。
  5. Card は、children を使って「枠」として再利用されています。

重要ポイント:

  • オブジェクトProps(profile)、Array Props(profiles)、Function Props(onFollow)、children(Card)、コンポーネントの再利用がすべて組み合わさっています。
  • 小さなプロフィールカードでも、Props設計を意識することで、一覧表示や再利用に耐えられる構造になります。

DAY 17:ミニ課題「プロフィールカード」のまとめ

このミニ課題では、

  • プロフィール情報をオブジェクトPropsとして profile にまとめて渡すこと
  • スキル一覧をArray Propsとして skills に渡し、SkillList で表示すること
  • 「フォローする」ボタンの動きをFunction Propsとして onFollow に渡し、子コンポーネントから親の処理を呼び出すこと
  • children を使って Card コンポーネントを「枠」として汎用化し、プロフィールやお知らせなどに再利用すること
  • ProfileList を通して、複数プロフィールを一覧表示しながら、同じコンポーネント群を再利用する流れ

をステップバイステップで確認しました。

読者のみなさんが、このプロフィールカードを自分なりにアレンジしてみることで、 Propsの設計力とコンポーネント再利用の感覚が、さらに深く身についていきます。

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