TEXTBOOK SECTION / AI LEARNING

基本コンポーネントを作る【実践】

Next.jsによるWebアプリケーション開発概論の「Next.js基礎:ReactコンポーネントとJSX・Propsの基本」より、基本コンポーネントを作る【実践】を解説。生成AI、AI活用、DX、業務改善を実践しながら学べるオンライン教材です。

8Next.js基礎:ReactコンポーネントとJSX・Propsの基本Next.js / Tailwind CSS / アプリ開発 / 開発 / Web開発

OVERVIEW

この節で学べること

概要を表示する
項目内容
教材名Next.jsによるWebアプリケーション開発概論
Next.js基礎:ReactコンポーネントとJSX・Propsの基本
基本コンポーネントを作る【実践】
カテゴリNext.js / Tailwind CSS / アプリ開発 / 開発 / Web開発
学習内容生成AI、AI活用、DX、業務改善を実践しながら理解するための教材です。

TABLE OF CONTENTS

目次

CONTENT

ここから

この節で学ぶこと

この節では、初めて自分でコンポーネントを作る体験を、手を動かしながら進めます。

React 公式では、コンポーネントは UI の再利用できる部品であり、JavaScript の関数として定義して使うと説明されています。

さらに、React の学習導線では「最初のコンポーネント」「props」「イベント処理」を順に学ぶ構成になっています。

この実践の到達目標は4つです。

  1. 1つの小さな表示部品を自分で作れることです。
  2. props を使って中身を差し替えられることです。
  3. クリックイベントを付けて「反応する部品」にできることです。
  4. Next.js の公式コンポーネント一覧ページを見て、次に何を学ぶとよいか見通しを持てることです。

Next.js 公式には next/imagenext/linknext/formnext/scriptnext/font などのコンポーネント API 一覧があります。

最初に見ておきたい考え方

コンポーネントは画面の部品

React 公式では、コンポーネントは UI の一部分であり、小さなボタンにも大きなページ全体にもなり得ると説明されています。

つまり、コンポーネントを作るとは、画面を意味のある部品へ分けることです。今回は、いきなり難しいものを作りません。

まずは「ラベルを表示する部品」、次に「props を受け取る部品」、最後に「クリックに反応する部品」という順番で進みます。この順番は、React 公式の基礎導線とも自然につながっています。

Next.js の中でも、やっていることは React コンポーネント作成

Next.js は React フレームワークであり、React Components で UI を作り、Next.js が追加機能や最適化を担当すると公式に説明されています。

したがって、app/page.tsx に書くものも、まずは React コンポーネントです。

つまり今やる練習は、「React の練習」であると同時に「Next.js のページを作る基礎練習」でもあります。ここがつながると、学習がかなり楽になります。

実践の準備

置き場所の考え方

Next.js の Project Structure では、app がルーティングとページの中心であり、プロジェクト整理のための推奨構成が案内されています。

再利用部品は components ディレクトリへ分ける構成がよく使われます。

今回は次のような構成で進めます。

src/
  app/
    page.tsx
  components/
    WelcomeCard.tsx
    ActionButton.tsx

app/page.tsx が画面の入口、components/ が再利用部品の置き場所、という分け方です。これは初心者にもかなり見通しがよい構成です。

Client Component が必要な場面

Next.js では、イベントハンドラや state などのインタラクティブな処理は Client Components 側で使うのが基本です。

公式でも、イベントハンドラや state は Client Component の代表例として説明されています。

そのため、クリックイベントを付ける部品では、ファイル先頭に 'use client' を付けます。今回はそこも含めて体験します。

実践1 文字を表示するコンポーネントを作る

手順

まず、src/components/WelcomeCard.tsx を作ります。React 公式では、コンポーネントは JavaScript の関数として定義し、マークアップを返すと説明されています。

export default function WelcomeCard() {
  return (
    <section>
      <h2>ようこそ</h2>
      <p>はじめてのコンポーネント作成です。</p>
    </section>
  )
}

次に、src/app/page.tsx で読み込みます。React 公式では、コンポーネントは import / export を通して別ファイルから使えると説明しています。

import WelcomeCard from '@/components/WelcomeCard'

export default function Page() {
  return (
    <main>
      <h1>トップページ</h1>
      <WelcomeCard />
    </main>
  )
}

これで、WelcomeCard という自作部品をページへ置けました。

見た目は小さいですが、ここで「定義する」「export する」「import する」「使う」という流れが一通りつながっています。

ここで確認したいこと

  • コンポーネント名は大文字始まりか
  • JSX を return しているか
  • page.tsx 側で import して使えているか

React 公式は、コンポーネント名は大文字で始める必要があると説明しています。これが崩れると、React は HTML タグと勘違いすることがあります。

実践2 Props を使って中身を変える

手順

次は、固定表示の部品を「外から内容を変えられる部品」へ進化させます。React 公式では、props は親コンポーネントから子コンポーネントへデータを渡す仕組みだと説明されています。

WelcomeCard.tsx を次のように書き換えます。

type WelcomeCardProps = {
  title: string
  message: string
}

export default function WelcomeCard({
  title,
  message,
}: WelcomeCardProps) {
  return (
    <section>
      <h2>{title}</h2>
      <p>{message}</p>
    </section>
  )
}

page.tsx も書き換えます。

import WelcomeCard from '@/components/WelcomeCard'

export default function Page() {
  return (
    <main>
      <h1>トップページ</h1>

      <WelcomeCard
        title="ようこそ"
        message="はじめての props 練習です。"
      />

      <WelcomeCard
        title="次の一歩"
        message="同じ部品を中身だけ変えて再利用できます。"
      />
    </main>
  )
}

これで、同じ WelcomeCard を2回使いながら、中身だけ変えられるようになりました。React 公式も、props によって同じコンポーネントを異なるデータで再利用できると説明しています。

ここで確認したいこと

  • props 名と受け取り側の名前が一致しているか
  • titlemessage の型が string になっているか
  • JSX の中で {title} {message} として表示できているか

TypeScript 公式では、オブジェクト型や type alias を使って、受け取るデータの形を明示できると説明しています。props 型定義は、初心者の段階でもかなり効果的です。

実践3 クリックできるコンポーネントを作る

手順

次はイベント処理です。React 公式では、イベントハンドラは JSX に追加する関数であり、クリックなどの操作に応じて実行されると説明しています。

src/components/ActionButton.tsx を作成します。

'use client'

type ActionButtonProps = {
  label: string
  onAction: () => void
}

export default function ActionButton({
  label,
  onAction,
}: ActionButtonProps) {
  return <button onClick={onAction}>{label}</button>
}

次に page.tsx を書き換えます。

import WelcomeCard from '@/components/WelcomeCard'
import ActionButton from '@/components/ActionButton'

export default function Page() {
  function handleGreeting() {
    alert('こんにちは。クリックされました。')
  }

  return (
    <main>
      <h1>トップページ</h1>

      <WelcomeCard
        title="ようこそ"
        message="イベント処理の練習を始めます。"
      />

      <ActionButton
        label="押してみる"
        onAction={handleGreeting}
      />
    </main>
  )
}

ここでは、親である page.tsxhandleGreeting を持ち、それを ActionButton に props として渡しています。React 公式でも、親が子へイベントハンドラを props として渡す設計が紹介されています。

ここで確認したいこと

  • ActionButton.tsx'use client' があるか
  • onClick={onAction} と、関数を渡す形になっているか
  • onClick={onAction()} のように、その場で実行していないか

React 公式は、イベントハンドラは passed, not called、つまり「渡すのであって、その場で呼ぶのではない」と強調しています。

実践4 children を使う

手順

次は、children を使って中身を自由に差し込める部品を作ります。React 公式では、ネストした JSX は children props としてコンポーネントへ渡されると説明しています。Fragment のページでも、要素を props として渡せることが示されています。

src/components/Panel.tsx を作ります。

import type { ReactNode } from 'react'

type PanelProps = {
  title: string
  children: ReactNode
}

export default function Panel({ title, children }: PanelProps) {
  return (
    <section>
      <h2>{title}</h2>
      <div>{children}</div>
    </section>
  )
}

page.tsx で使います。

import WelcomeCard from '@/components/WelcomeCard'
import ActionButton from '@/components/ActionButton'
import Panel from '@/components/Panel'

export default function Page() {
  function handleGreeting() {
    alert('こんにちは。クリックされました。')
  }

  return (
    <main>
      <h1>トップページ</h1>

      <Panel title="学習メモ">
        <p>children を使うと、枠だけ共通化できます。</p>
        <ActionButton
          label="押してみる"
          onAction={handleGreeting}
        />
      </Panel>

      <WelcomeCard
        title="まとめ"
        message="コンポーネントを組み合わせて画面を作れます。"
      />
    </main>
  )
}

これで Panel は「タイトル付きの枠」として再利用できるようになります。中に何を入れるかは使う側が決められます。React 公式でも、children はラッパー系コンポーネントで特に有効だと説明されています。

練習問題

問1

HelloCard というコンポーネントを作ってください。

条件は次のとおりです。

  • 見出しに「Hello」
  • 本文に「最初の練習です」
  • export default function HelloCard() の形で書く

答え

export default function HelloCard() {
  return (
    <section>
      <h2>Hello</h2>
      <p>最初の練習です</p>
    </section>
  )
}

解説

React 公式では、コンポーネントは JavaScript の関数として定義し、マークアップを返すと説明されています。まずは props なしの固定部品を作るのがよい練習です。

問2

ProfileCard というコンポーネントを作ってください。

条件は次のとおりです。

  • name を props で受け取る
  • <h2>name を表示する
  • TypeScript で型を付ける

答え

type ProfileCardProps = {
  name: string
}

export default function ProfileCard({
  name,
}: ProfileCardProps) {
  return (
    <section>
      <h2>{name}</h2>
    </section>
  )
}

解説

React 公式では、props は親から子へデータを渡す仕組みです。TypeScript で型を付けると、その部品が何を受け取るのかが明確になります。

問3

次のコードの問題点を答えてください。

'use client'

type ButtonProps = {
  onAction: () => void
}

export default function Button({ onAction }: ButtonProps) {
  return <button onClick={onAction()}>押す</button>
}

答え

onClick に 関数を渡す べきなのに、onAction() と書いて その場で実行している のが問題です。

修正版は次です。

'use client'

type ButtonProps = {
  onAction: () => void
}

export default function Button({ onAction }: ButtonProps) {
  return <button onClick={onAction}>押す</button>
}

解説

React 公式では、イベントハンドラは passed, not called と説明されています。onClick={onAction} は正しく、onClick={onAction()} はレンダリング時に実行されてしまいます。

問4

Card というコンポーネントを作ってください。

条件は次のとおりです。

  • children を受け取る
  • <div> の中に children を表示する
  • childrenReactNode 型にする

答え

import type { ReactNode } from 'react'

type CardProps = {
  children: ReactNode
}

export default function Card({ children }: CardProps) {
  return <div>{children}</div>
}

解説

React では、コンポーネントタグの中へネストした内容は children props として渡されます。ラッパー系コンポーネントの基本形です。

問5

次のようなコンポーネントを作りたいです。

  • タイトル付きの枠
  • 中身は自由に差し込める
  • ボタンや文章も入れられる

このとき使うとよい props は何ですか。

答え

children を使うとよいです。

解説

React 公式では、children はネストした JSX を受け取るための特別な props として説明されています。枠だけ共通化して中身を自由にしたい場面で特に有効です。

参考になる外部ページ

React の公式学習ページ

最初のコンポーネント作成や props の感覚を確認するには、次の React 公式ページが特に参考になります。

Next.js の公式コンポーネント一覧ページ

Next.js の「標準で使えるコンポーネント」をまとめて見るには、Components - API Reference がいちばん使いやすいです。ここには ImageLinkFormScriptFont などが並んでいます。

特に最初に見ると良いページは次のページです。

  • Components - API Reference

Next.js のコンポーネント一覧。

  • Image Componentnext/image の基本。画像最適化付き。
  • Link Componentnext/link の基本。ルーティング用。
  • Architecture

コンポーネントやファイル規約を広く見渡したいときに有用。

まとめ

初めてコンポーネントを作るときにいちばん大切なのは、完璧な部品を作ることではなく、小さく作って、ページで使って、少しずつ再利用できる形へ寄せることです。

React 公式の導線でも、最初のコンポーネント、props、イベント処理、UI の分解という順番で学ぶようになっています。

今回の実践で押さえたいのは次の4点です。

  • コンポーネントは JavaScript / TypeScriptの関数として作る。
  • props を使うと同じ部品を中身だけ変えて再利用できる。
  • イベント処理を使う部品は Next.js では Client Component 側に置く。
  • children を使うと、枠だけ共通化して中身を自由に差し込める。

ここまできたら、手を動かして経験を積むだけになります。試行錯誤しながら進めていってください。

参考文献

  • React Docs, Your First Component.
  • React Docs, Passing Props to a Component.
  • React Docs, Quick Start.
  • React Docs, Thinking in React.
  • React Docs, Fragment.
  • Next.js Docs, Components - API Reference.
  • Next.js Docs, Image Component.
  • Next.js Docs, Link Component.
  • Next.js Docs, Architecture.
  • Next.js Docs, Getting Started: Server and Client Components.

FAQ

よくある質問

基本コンポーネントを作る【実践】は医療関係者向けだけの内容ですか。
医療分野の例が含まれる場合もありますが、医療関係者だけに限定した内容ではありません。生成AI、AI活用、DX、業務改善、プロトタイプ開発など、一般的なAI学習の事例として読める内容です。
AI初心者でも読めますか。
はい。AIをこれから学ぶ方、数学が苦手な方、仕事でAIを使いたい方にも読み進めやすいように、教材の章と節の流れに沿って整理しています。
サムネイル画像は必ず表示されますか。
はい。教材にcoverUrlが設定されている場合はその画像を表示し、未設定の場合は代替サムネイル画像を表示します。
Next.jsによるWebアプリケーション開発概論のほかの章も読めますか。
はい。教材トップから章立てを確認でき、前後の節へもページ下部のナビゲーションから移動できます。