前回、カードを1枚書きました。今回はそれを部品として切り出します。
Reactでいう部品(コンポーネント)の正体は、JSXを返す関数です。それだけです。
function BirdCard() {
return <div className="card">🐦 シマエナガ</div>
}使うときは、自分で作ったHTMLタグのように書きます。
<BirdCard />決まりは2つだけ
コンポーネントとして扱われるための条件は、たった2つです。
- 名前を大文字で始める
- JSXを返す
ファイルに切り出す
コンポーネントはApp.jsxの中に書いても動きますが、1つのファイルに1つの部品にしておくと、後から探しやすくなります。慣習としてsrc/components/にまとめます。
function BirdCard() {
return (
<div className="flex max-w-md gap-4 rounded-2xl bg-white p-5 shadow-sm">
<span className="text-4xl">🐦</span>
<div>
<h2 className="font-bold text-slate-800">シマエナガ</h2>
<p className="mt-1 text-sm text-slate-600">
雪のようにまっ白な小鳥。北海道にすんでいる。
</p>
</div>
</div>
)
}
export default BirdCard最後のexport default BirdCardが「このファイルの主役はこれです」という宣言です。これを書き忘れると、読みこむ側でundefinedになり「Element type is invalid」というエラーになります。
読みこむ側はこうです。
import BirdCard from './components/BirdCard.jsx'
function App() {
return (
<div className="min-h-screen bg-sky-50 p-8">
<h1 className="text-2xl font-bold text-sky-800">しまちゃんのことりずかん</h1>
<p className="mt-1 text-sm text-slate-500">全8羽をあつめよう</p>
<div className="mt-6 space-y-4">
<BirdCard />
<BirdCard />
<BirdCard />
</div>
</div>
)
}
export default App./から始まるパスは「このファイルと同じ場所から数えて」という意味です。App.jsxがsrc/にあるので、./components/BirdCard.jsxでsrc/components/BirdCard.jsxにたどりつきます。
./と../の数え方があやしい人はこちら。HTMLのときと考え方は同じです<BirdCard />と<BirdCard></BirdCard>
中身を持たない部品は、自分で閉じる書き方にします。
<BirdCard />中に何か入れたいときは、開始タグと終了タグで挟みます。挟んだ中身はchildrenという名前で受け取れます(次回扱います)。
<Layout>
<BirdCard />
</Layout>部品にすると何がうれしいのか
上のコードでは<BirdCard />を3回書いています。3枚のカードが並びますが、中身は全部同じです。
もうひとつの利点はまとまりに名前が付くことです。App.jsxを開いたときに、
<Header />
<SearchBox />
<BirdList />と並んでいれば、中身を読まなくても画面の構造が分かります。WordPressのテンプレートでget_header()やget_template_part('parts/card')を並べるのと、読み心地は同じです。
どこまで細かく分けるか
最初から細かく割る必要はありません。名前が付けられるまとまりになったら切り出す——それで十分です。
| 切り出す価値がある | まだ切り出さなくていい |
|---|---|
| カード・ヘッダー・検索ボックス(呼び名がある) | <div>で囲っただけのまとまり |
| 同じ形を何度も使う | 1回しか出てこない小さな飾り |
| 中で状態を持つようになった | 数行のJSX |
公式ドキュメントも見てみる
ja.react.dev外部サイト初めてのコンポーネント – React公式の「最初のコンポーネント」。「コンポーネントを定義する」の節に、大文字で始める理由とexport defaultの使い方が短くまとまっていますこのレッスンのまとめ
- コンポーネントの正体はJSXを返す関数
- 名前は必ず大文字で始める——小文字だとHTMLタグ扱いになり、何も出ないまま静かに失敗する
src/components/に1ファイル1部品で置き、export defaultで書き出す- 読みこむ側は
import BirdCard from './components/BirdCard.jsx' - 部品にしただけでは同じ中身しか作れない——次回の
propsで1枚ずつ変える
