初めてのコンポーネント

コンポーネントはReactの中核概念の1つです。ユーザーインターフェース(UI)を構築するための基盤であり、Reactの学習を始めるのに最適な場所です!

学ぶこと

  • コンポーネントとは何か
  • Reactアプリケーションにおけるコンポーネントの役割
  • 最初のReactコンポーネントの書き方

コンポーネント:UI構築ブロック

ウェブ上では、HTMLを使用することで、<h1><li>のような組み込みのタグセットを使用して、構造化された豊富なドキュメントを作成できます。

<article>
<h1>My First Component</h1>
<ol>
<li>Components: UI Building Blocks</li>
<li>Defining a Component</li>
<li>Using a Component</li>
</ol>
</article>

このマークアップは、この記事<article>、その見出し<h1>、そして(省略された)目次を順序付きリスト<ol>として表しています。このようなマークアップは、スタイルのためのCSSやインタラクティビティのためのJavaScriptと組み合わされ、ウェブ上で見られるすべてのサイドバー、アバター、モーダル、ドロップダウン、つまりすべてのUI要素の背後にあるものです。

Reactでは、マークアップ、CSS、JavaScriptをカスタム「コンポーネント」つまり、アプリケーション用の再利用可能なUI要素にまとめることができます。上記で見た目次コードは、<TableOfContents />コンポーネントに変換でき、どのページにもレンダリングできます。内部的には、<article><h1>などの同じHTMLタグを使用しています。

HTMLタグと同様に、コンポーネントを構成、順序付け、ネストして、全体のページを設計できます。たとえば、あなたが読んでいるこのドキュメントページは、Reactコンポーネントで構成されています。

<PageLayout>
<NavigationHeader>
<SearchBar />
<Link to="/docs">Docs</Link>
</NavigationHeader>
<Sidebar />
<PageContent>
<TableOfContents />
<DocumentationText />
</PageContent>
</PageLayout>

プロジェクトが成長するにつれて、多くのデザインが既に作成したコンポーネントの再利用によって構成できることに気づき、開発速度が向上します。上記の目次を、<TableOfContents />を使って任意の画面に追加できます! Chakra UIMaterial UIのような、Reactオープンソースコミュニティによって共有されている何千ものコンポーネントを使用して、プロジェクトをすぐに開始することもできます。

コンポーネントの定義

従来、ウェブページを作成する際、ウェブ開発者はコンテンツにマークアップを施し、JavaScriptを散りばめることでインタラクションを追加していました。これは、インタラクションがウェブ上では便利な機能だったときにはうまく機能しました。今では多くのサイト、そしてすべてのアプリで期待されています。Reactはインタラクションを優先的に扱いながら、同じ技術を使用しています。Reactコンポーネントは、マークアップを散りばめることができるJavaScript関数です。それがどのようなものかを示します(以下の例を編集できます)。

export default function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3Am.jpg"
      alt="Katherine Johnson"
    />
  )
}

そして、コンポーネントの構築方法を示します。

ステップ1:コンポーネントのエクスポート

export defaultプレフィックスは標準的なJavaScript構文(React固有のものではありません)。これにより、ファイル内のメイン関数をマークし、後で他のファイルからインポートできます。(インポートの詳細については、コンポーネントのインポートとエクスポートを参照してください!)

ステップ2: 関数の定義

function Profile() { } は、Profileという名前のJavaScript関数を定義します。

注意点

Reactコンポーネントは通常のJavaScript関数ですが、名前の先頭は大文字にする必要があります。そうでないと動作しません!

ステップ3: マークアップの追加

このコンポーネントは、<img />タグをsrc属性とalt属性と共に返します。<img />はHTMLのように記述されていますが、実際には内部的にはJavaScriptです。この構文はJSXと呼ばれ、JavaScript内にマークアップを埋め込むことができます。

return文は、このコンポーネントのようにすべて一行に記述できます。

return <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />;

しかし、マークアップがreturnキーワードと同じ行にない場合は、括弧で囲む必要があります。

return (
<div>
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
</div>
);

注意点

括弧がない場合、returnの後の行にあるコードは無視されます

コンポーネントの使用

これでProfileコンポーネントを定義したので、他のコンポーネントの中にネストできます。例えば、複数のProfileコンポーネントを使用するGalleryコンポーネントをエクスポートできます。

function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

ブラウザが表示するもの

大文字と小文字の違いに注目してください。

  • <section>は小文字なので、ReactはHTMLタグを参照していると認識します。
  • <Profile />は大文字のPで始まるため、ReactはProfileというコンポーネントを使用したいと認識します。

そしてProfileにはさらに多くのHTML(<img />)が含まれています。最終的に、ブラウザが表示するのはこれです。

<section>
<h1>Amazing scientists</h1>
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
</section>

コンポーネントのネストと整理

コンポーネントは通常のJavaScript関数なので、複数のコンポーネントを同じファイルに保持できます。これは、コンポーネントが比較的小さかったり、互いに密接に関連している場合に便利です。ファイルが混雑してきた場合は、いつでもProfileを別のファイルに移動できます。インポートに関するページで、その方法をすぐに学ぶことができます。インポートとエクスポートに関するページ

ProfileコンポーネントはGallery内でレンダリングされています(複数回も!)。そのため、Gallery親コンポーネントであり、各Profileを「子」としてレンダリングしていると見なすことができます。これがReactの魔法の一部です。コンポーネントを一度定義すれば、好きな場所で何度でも使用できます。

注意点

コンポーネントは他のコンポーネントをレンダリングできますが、定義をネストすることは決してできません。

export default function Gallery() {
// 🔴 Never define a component inside another component!
function Profile() {
// ...
}
// ...
}

上記のコードスニペットは非常に遅く、バグの原因となります。代わりに、すべてのコンポーネントを最上位レベルで定義してください。

export default function Gallery() {
// ...
}

// ✅ Declare components at the top level
function Profile() {
// ...
}

子コンポーネントが親からデータを取得する必要がある場合、定義をネストするのではなく、propsで渡してください

詳細

最下層までのコンポーネント

Reactアプリケーションは「ルート」コンポーネントから始まります。通常、新しいプロジェクトを開始すると自動的に作成されます。CodeSandboxNext.jsなどのフレームワークを使用する場合、ルートコンポーネントはpages/index.jsに定義されています。これらの例では、ルートコンポーネントをエクスポートしていました。

ほとんどのReactアプリでは、最下層までコンポーネントを使用します。これは、ボタンなどの再利用可能な部品だけでなく、サイドバー、リスト、そして最終的には完全なページのようなより大きな部品にもコンポーネントを使用することを意味します!コンポーネントは、一度しか使用されないコンポーネントであっても、UIコードとマークアップを整理する便利な方法です。

Reactベースのフレームワークは、さらに一歩進んでいます。空のHTMLファイルを使用し、JavaScriptでページの管理をReactに「引き継がせる」のではなく、ReactコンポーネントからHTMLも自動的に生成します。これにより、JavaScriptコードがロードされる前に、アプリにコンテンツを表示できます。

それでも、多くのウェブサイトでは、既存のHTMLページにインタラクティブ性を追加する目的でReactを使用しているに過ぎません。ページ全体に対して単一のルートコンポーネントではなく、多くのルートコンポーネントが存在します。必要に応じて、Reactを多く使用することも、少しだけ使用することもできます。

まとめ

Reactを初めて体験しましたね!重要な点をいくつかまとめてみましょう。

  • Reactを使用すると、コンポーネント、つまりアプリケーション用の再利用可能なUI要素を作成できます。

  • Reactアプリケーションでは、UIのあらゆる部分がコンポーネントです。

  • Reactコンポーネントは通常のJavaScript関数ですが、以下の点が異なります。

    1. 名前は常に大文字で始まります。
    2. JSXマークアップを返します。

チャレンジ 1 4:
コンポーネントのエクスポート

ルートコンポーネントがエクスポートされていないため、このサンドボックスは機能しません。

function Profile() {
  return (
    <img
      src="https://i.imgur.com/lICfvbD.jpg"
      alt="Aklilu Lemma"
    />
  );
}

解決策を見る前に、自分で修正してみてください!