コンポーネントは関数である

Part 2 · コンポーネントと props

コンポーネントは関数である

画面の部品を関数として切り出す

React は「コンポーネントを作って組み合わせる」ライブラリだと説明されます。 そう聞くと、何か特別な仕組みがあるように思えます。

ですが実体は拍子抜けするほど単純です。コンポーネントとは、JSX を返すただの関数です。 それ以上でも以下でもありません。

JSX を返す関数、それだけ

前の章で「JSX は値である」と確かめました。 値なら、関数から返せます。それがコンポーネントです。

function Greeting() {
  return <p>こんにちは</p>;
}

特別な書き方も、継承する親クラスもありません。JSX を返す関数を書けば、それはもうコンポーネントです。

そして作ったコンポーネントは、タグとして書けます。 同じものを何度でも置けます。

同じ部品を 3 回置く

関数を 1 つ書いて、3 回使っている

こんにちは

こんにちは

こんにちは

greeting.tsx

// コンポーネントは、JSX を返すただの関数
function Greeting() {
  return <p className="rounded-md border p-2.5">こんにちは</p>;
}

// 大文字で始まっていれば、タグとして書ける
export function Greetings() {
  return (
    <div className="flex flex-col gap-2.5">
      <Greeting />
      <Greeting />
      <Greeting />
    </div>
  );
}

名前は必ず大文字で始める

コンポーネントの名前は、大文字で始めなければいけません。 これは好みの問題ではなく、動作が変わります。

<Greeting />   // 大文字 → 自分で作ったコンポーネント
<greeting />   // 小文字 → HTML のタグとして扱われる

React は頭文字だけを見て、 「これは自作の部品か、それとも HTML のタグか」を判断しています。 小文字で書くと、React はgreeting という名前の HTML タグを探しに行きます。 そんなタグは存在しないので、画面には何も出ません。

greeting.tsx

// コンポーネントは、JSX を返すただの関数
function Greeting() {
  return <p className="rounded-md border p-2.5">こんにちは</p>;
}

// 大文字で始まっていれば、タグとして書ける
export function Greetings() {
  return (
    <div className="flex flex-col gap-2.5">
      <Greeting />
      <Greeting />
      <Greeting />
    </div>
  );
}

小さく作って、組み合わせる

コンポーネントは、別のコンポーネントの中で使えます。 小さい部品を作り、それを並べて大きい部品を作っていきます。

部品を組み合わせたカード

Avatar と Name を並べただけ

さとう

デザイナー

ProfileCard の中身を見ると、何が置いてあるかが一目で分かります。 アバターと名前が横に並んでいる、それだけです。

もし分けずに全部書いていたら、divclassName が入り混じった塊になり、 何のためのコードか読み取るのに時間がかかります。

分けると何が良いのか

  • 読める … 名前が付くので、中を読まなくても何かが分かる
  • 使い回せる … 同じ見た目が必要な場所で再利用できる
  • 直す範囲が狭い … アバターを丸から四角に変えたいなら、Avatar だけを見ればいい

profile-card.tsx

// 小さい部品を作って
function Avatar() {
  return (
    <div className="flex size-10 shrink-0 items-center justify-center rounded-full border font-semibold">

    </div>
  );
}

function Name() {
  return (
    <div>
      <p className="font-semibold">さとう</p>
      <p className="text-muted-foreground">デザイナー</p>
    </div>
  );
}

// 組み合わせて大きい部品にする
export function ProfileCard() {
  return (
    <div className="flex items-center gap-3 rounded-md border p-3">
      <Avatar />
      <Name />
    </div>
  );
}

理解できたか確かめる

確認クイズ

React のコンポーネントとは何?

確認クイズ

作ったコンポーネントが画面に出ない。まず疑うのは?

greeting.tsx

// コンポーネントは、JSX を返すただの関数
function Greeting() {
  return <p className="rounded-md border p-2.5">こんにちは</p>;
}

// 大文字で始まっていれば、タグとして書ける
export function Greetings() {
  return (
    <div className="flex flex-col gap-2.5">
      <Greeting />
      <Greeting />
      <Greeting />
    </div>
  );
}

この章のまとめ

  • コンポーネントはJSX を返すただの関数
  • 名前は大文字で始める。小文字だと HTML タグ扱いになり、無言で消える
  • 小さい部品を組み合わせて、大きい部品を作る
  • 分ける目的は、読みやすさ・再利用・直す範囲を狭くすること

greeting.tsx

// コンポーネントは、JSX を返すただの関数
function Greeting() {
  return <p className="rounded-md border p-2.5">こんにちは</p>;
}

// 大文字で始まっていれば、タグとして書ける
export function Greetings() {
  return (
    <div className="flex flex-col gap-2.5">
      <Greeting />
      <Greeting />
      <Greeting />
    </div>
  );
}