発行:

コンポーネント

Next.js(React)開発の醍醐味である「コンポーネント」について学びましょう。
コンポーネントを使いこなすことが、効率的なWebアプリ開発への近道です。

コンポーネントとは?

コンポーネントとは、 「見た目と機能を持った再利用可能な部品」 のことです。
ヘッダー、フッター、ボタン、カード型のリストアイテムなど、画面上のあらゆる要素をコンポーネントとして分割して作ります。

イメージとしては、 「自分だけのオリジナルHTMLタグを作る」 感覚に近いです。
通常のHTMLには <div><button> などのタグがありますが、これらを組み合わせて <MyButton><Header> といった新しいタグ(コンポーネント)を作ることができます。

Next.jsでのコンポーネント作成

Next.js (App Router) では、src/app 内や src/app/_components(※アンダースコアを付けるとルーティング対象外になります)などにコンポーネントファイルを作成します。

ファイル構成の例

今回は練習として、以下のような構成で作成してみましょう。

Directory
src/app/
├── globals.css
├── layout.tsx
├── page.tsx
├── hello/
│   └── page.tsx              # 確認用ページ
└── _components/              # コンポーネント置き場
    ├── MyComponent.tsx       # 基本のコンポーネント
    ├── MsgComponent.tsx      # Propsを使うコンポーネント
    └── CmtComponent.tsx      # childrenを使うコンポーネント

Step 1: 基本的なコンポーネントの作成

まずは一番シンプルなコンポーネントを作ってみます。
src/app/_components/MyComponent.tsx を作成し、以下のコードを記述します。

src/app/_components/MyComponent.tsx
export default function MyComponent() {
  return (
    <div className="p-4 border border-gray-300 rounded">
      Hello My Component!
    </div>
  );
}

これがコンポーネントの基本形です。関数(function)として定義し、その戻り値として表示したいJSX(HTMLのようなもの)を返します。

作ったコンポーネントを使ってみる

src/app/hello ディレクトリを作成し、その中の page.tsx から呼び出してみましょう。

src/app/hello/page.tsx
import MyComponent from '../_components/MyComponent';

export default function HelloPage() {
  return (
    <div className="p-8">
      <h1 className="text-2xl font-bold mb-4">Hello Sample Page</h1>
      {/* 自作コンポーネントを配置 */}
      <MyComponent />
    </div>
  );
}

開発サーバーを起動し、http://localhost:3000/hello にアクセスすると、枠で囲まれた "Hello My Component!" が表示されるはずです。

Next.js コンポーネントサンプルページ

Step 2: データを渡す (Props)

コンポーネントは、外部からデータを受け取って表示内容を変えることができます。この受け取るデータを 「Props(プロップス)」 と呼びます。

src/app/_components/MsgComponent.tsx を作成します。

src/app/_components/MsgComponent.tsx
// Propsの型定義
type Props = {
  message: string;
};

export default function MsgComponent({ message }: Props) {
  return (
    <div className="text-blue-500 font-semibold my-2">
      Message: {message}
    </div>
  );
}

{ message }: Props の部分で、親から渡されたデータを受け取っています。

Propsを使ってみる

src/app/hello/page.tsx を編集して、MsgComponent を使ってみましょう。

src/app/hello/page.tsx
import MyComponent from '../_components/MyComponent';
import MsgComponent from '../_components/MsgComponent';

export default function HelloPage() {
  return (
    <div className="p-8">
      <h1 className="text-2xl font-bold mb-4">Hello Sample Page</h1>

      <MyComponent />

      {/* 以下の2つは同じコンポーネントですが、渡すメッセージが違います */}
      <MsgComponent message="こんにちは!" />
      <MsgComponent message="Next.jsは楽しいですね" />
    </div>
  );
}

Next.js コンポーネントサンプルページ

同じコンポーネントを使い回しながら、表示する内容だけを変えることができました。これがコンポーネント化の大きなメリットです。

Step 3: 子要素を渡す (children)

HTMLの <div>ここに中身</div> のように、コンポーネントのタグで囲んだ中身を受け取りたい場合は、 children という特別なPropsを使います。

src/app/_components/CmtComponent.tsx を作成します。

src/app/_components/CmtComponent.tsx
type Props = {
  children: React.ReactNode; // 子要素は ReactNode 型になります
};

export default function CmtComponent({ children }: Props) {
  return (
    <div className="bg-gray-100 p-4 rounded-lg my-4">
      <div className="text-xs text-gray-400 mb-1">Comment Area</div>
      <div className="text-gray-800">
        {children}
      </div>
    </div>
  );
}

children を使ってみる

src/app/hello/page.tsx をさらに編集します。

src/app/hello/page.tsx
import MyComponent from '../_components/MyComponent';
import MsgComponent from '../_components/MsgComponent';
import CmtComponent from '../_components/CmtComponent';

export default function HelloPage() {
  return (
    <div className="p-8">
      <h1 className="text-2xl font-bold mb-4">Hello Sample Page</h1>

      <MyComponent />

      <MsgComponent message="Propsのテストです" />

      <CmtComponent>
        ただのテキストを挟むことができます。
      </CmtComponent>

      <CmtComponent>
        {/* HTMLタグごとも渡せます */}
        <p><strong>強調されたテキスト</strong>や、</p>
        <button className="bg-blue-500 text-white px-2 py-1 rounded">ボタン</button>
        なども自由に入れられます。
      </CmtComponent>
    </div>
  );
}

children を使うことで、枠組み(背景色やパディングなど)だけを共通化し、中身は自由に差し替えられるコンポーネントが作れます。

まとめ

  • コンポーネント : UIを部品化して再利用する仕組み。
  • Props : 親から子へデータを渡す仕組み(引数のようなもの)。
  • children : タグの中身を丸ごと受け取る特別なProps。

これで、Next.js (React) の画面構築の基礎が理解できました。
次章では、コンポーネントを見栄え良くするための「スタイル(CSS)」について解説します。