UI の記述

React は、ユーザインターフェース(UI)を表示するための JavaScript ライブラリです。UI はボタンやテキスト、画像といった小さな要素から構成されています。React ではこれらを、ネストして再利用できるコンポーネントにまとめることができます。ウェブサイトであれ携帯電話アプリであれ、画面上のすべてのものはコンポーネントに分解することができます。この章では、React コンポーネントを作成し、カスタマイズし、条件付きで表示する方法について学びます。

初めてのコンポーネント

React アプリケーションはコンポーネントと呼ばれる独立した UI のパーツで構成されています。React コンポーネントとは、マークアップを添えることができる JavaScript 関数です。コンポーネントは、ボタンのような小さなものであることもあれば、ページ全体といった大きなものであることもあります。以下は、3 つの 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>
  );
}

Ready to learn this topic?

初めてのコンポーネントを読んで、React コンポーネントの宣言方法、使用方法について学びましょう。

Read More

コンポーネントのインポートとエクスポート

1 つのファイルに多くのコンポーネントを宣言することもできますが、大きなファイルは取り回しが難しくなります。これを解決するために、コンポーネントを個別のファイルにエクスポートし、別のファイルからそのコンポーネントをインポートすることができます。

import Profile from './Profile.js';

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

Ready to learn this topic?

コンポーネントのインポートとエクスポートを読んで、コンポーネントを個々の専用ファイルに分割する方法を学びましょう。

Read More

JSX でマークアップを記述する

各 React コンポーネントは、ブラウザにレンダーされるマークアップを含んだ JavaScript 関数です。React コンポーネントは、マークアップを表現するために JSX という拡張構文を使用します。JSX は HTML によく似ていますが、少し構文が厳密であり、動的な情報を表示することができます。

既存の HTML マークアップを React コンポーネントに貼り付けても、常にうまく機能するわけではありません。

export default function TodoList() {
  return (
    // This doesn't quite work!
    <h1>Hedy Lamarr's Todos</h1>
    <img
      src="https://i.imgur.com/yXOvdOSs.jpg"
      alt="Hedy Lamarr"
      class="photo"
    >
    <ul>
      <li>Invent new traffic lights
      <li>Rehearse a movie scene
      <li>Improve spectrum technology
    </ul>

このような既存の HTML がある場合は、コンバータを使って修正することができます。

export default function TodoList() {
  return (
    <>
      <h1>Hedy Lamarr's Todos</h1>
      <img
        src="https://i.imgur.com/yXOvdOSs.jpg"
        alt="Hedy Lamarr"
        className="photo"
      />
      <ul>
        <li>Invent new traffic lights</li>
        <li>Rehearse a movie scene</li>
        <li>Improve spectrum technology</li>
      </ul>
    </>
  );
}

Ready to learn this topic?

JSX でマークアップを記述するを読んで、正しい JSX の書き方を学びましょう。

Read More

JSX に波括弧で JavaScript を含める

JSX を使うことで、JavaScript ファイル内に HTML のようなマークアップを記述し、レンダーのロジックとコンテンツを同じ場所に配置することができます。時には、そのマークアップ内でちょっとした JavaScript ロジックを追加したり、動的なプロパティを参照したりしたいことがあります。このような状況では、JSX 内で波括弧を使い JavaScript への「窓を開ける」ことができます。

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}

Ready to learn this topic?

JSX に波括弧で JavaScript を含めるを読んで、JSX 内から JavaScript のデータにアクセスする方法を学びましょう。

Read More

コンポーネントに props を渡す

React コンポーネントでは、props を使ってお互いに情報をやり取りします。親コンポーネントは、子コンポーネントに props を与えることで、情報を渡すことができます。HTML の属性 (attribute) と似ていますが、オブジェクト、配列、関数、そして JSX まで、どのような JavaScript の値でも渡すことができます!

import { getImageUrl } from './utils.js'

export default function Profile() {
  return (
    <Card>
      <Avatar
        size={100}
        person={{
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
    </Card>
  );
}

function Avatar({ person, size }) {
  return (
    <img
      className="avatar"
      src={getImageUrl(person)}
      alt={person.name}
      width={size}
      height={size}
    />
  );
}

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

Ready to learn this topic?

コンポーネントに props を渡すを読んで、props の渡し方と読み取り方を学びましょう。

Read More

条件付きレンダー

コンポーネントは、さまざまな条件によって表示内容を切り替える必要がよくあります。React では、JavaScript の if 文、&&? : 演算子などの構文を使って、条件付きで JSX をレンダーすることができます。

この例では、JavaScript の && 演算子を使い、チェックマークを条件付きでレンダーしています。

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✅'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}

Ready to learn this topic?

条件付きレンダーを読んで、コンテンツを条件付きでレンダーするためのさまざまな方法を学びましょう。

Read More

リストのレンダー

データの集まりから複数のよく似たコンポーネントを表示したいことがよくあります。React で JavaScript の filter()map() を使って、データの配列をフィルタリングしたり、コンポーネントの配列に変換したりすることができます。

配列内の各要素には、key を指定する必要があります。通常、データベースの ID を key として使うことになるでしょう。key は、リストが変更されても各アイテムのリスト内の位置を React が追跡できるようにするために必要です。

import { people } from './data.js';
import { getImageUrl } from './utils.js';

export default function List() {
  const listItems = people.map(person =>
    <li key={person.id}>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}
        known for {person.accomplishment}
      </p>
    </li>
  );
  return (
    <article>
      <h1>Scientists</h1>
      <ul>{listItems}</ul>
    </article>
  );
}

Ready to learn this topic?

リストのレンダーを読んで、コンポーネントのリストをレンダーする方法と、key の選択方法を学びましょう。

Read More

コンポーネントを純粋に保つ

いくつかの JavaScript の関数は純関数です。純関数には以下の特徴があります。

  • 自分の仕事に集中する。呼び出される前に存在していたオブジェクトや変数を変更しない。
  • 同じ入力には同じ出力。同じ入力を与えると、純関数は常に同じ結果を返す。

コンポーネントを常に厳密に純関数として書くことで、コードベースが成長するにつれて起きがちな、あらゆる種類の不可解なバグ、予測不可能な挙動を回避することができます。以下は純粋ではないコンポーネントの例です。

let guest = 0;

function Cup() {
  // Bad: changing a preexisting variable!
  guest = guest + 1;
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup />
      <Cup />
      <Cup />
    </>
  );
}

このコンポーネントを純粋にするには、既に存在する変数を書き換えるのではなく、prop を渡すようにすることができます。

function Cup({ guest }) {
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup guest={1} />
      <Cup guest={2} />
      <Cup guest={3} />
    </>
  );
}

Ready to learn this topic?

コンポーネントを純粋に保つを読んで、予測可能な純関数としてコンポーネントを作成する方法を学びましょう。

Read More

UI をツリーとして理解する

React はコンポーネント間あるいはモジュール間の関係性をモデル化するために、ツリー構造を使用します。

React レンダーツリーとはコンポーネントの親子関係を表現したものです。

5 つのノードからなるツリー。それぞれのノードはコンポーネントを表している。ルートノードはツリーの最上部にあり 'Root Component' と書かれている。そこから 2 本の矢印が下に伸びており 'Component A' および 'Component C' と書かれたノードを指している。それぞれの矢印には 'renders' と書かれている。'Component A' からは 'renders' と書かれた矢印が 'Component B' と書かれたノードに伸びている。'Component C' からは 'renders' と書かれた矢印が 'Component D' と書かれたノードに伸びている。
5 つのノードからなるツリー。それぞれのノードはコンポーネントを表している。ルートノードはツリーの最上部にあり 'Root Component' と書かれている。そこから 2 本の矢印が下に伸びており 'Component A' および 'Component C' と書かれたノードを指している。それぞれの矢印には 'renders' と書かれている。'Component A' からは 'renders' と書かれた矢印が 'Component B' と書かれたノードに伸びている。'Component C' からは 'renders' と書かれた矢印が 'Component D' と書かれたノードに伸びている。

React のレンダーツリーの例

ツリーの上側、つまりルートに近いコンポーネントはトップレベルコンポーネントです。子を持たないコンポーネントはリーフ(葉)コンポーネントです。このようなコンポーネントの分類は、データの流れやレンダーパフォーマンスを理解する際に有用です。

アプリを理解する上では、JavaScript のモジュール間の関係性をモデルすることも重要です。このようなものをモジュール依存関係ツリーと呼びます。

5 つのノードからなるツリー。それぞれのノードは JavaScript のモジュールを表している。最上部のノードは 'RootModule.js' と書かれている。そこから 'ModuleA.js'、'ModuleB.js'、'ModuleC.js' へと 3 本の矢印が伸びている。各矢印には 'imports' と書かれている。'ModuleC.js' からは 'imports' と書かれた矢印が 'ModuleD.js' と書かれたノードに伸びている。
5 つのノードからなるツリー。それぞれのノードは JavaScript のモジュールを表している。最上部のノードは 'RootModule.js' と書かれている。そこから 'ModuleA.js'、'ModuleB.js'、'ModuleC.js' へと 3 本の矢印が伸びている。各矢印には 'imports' と書かれている。'ModuleC.js' からは 'imports' と書かれた矢印が 'ModuleD.js' と書かれたノードに伸びている。

モジュール依存関係ツリーの例

依存関係ツリーは、関連する JavaScript コードをすべてバンドルしてクライアントがダウンロード・レンダーできるようにするために、ビルドツールでよく使用されます。バンドルサイズが大きいと、React アプリのユーザ体験は悪化します。モジュール依存関係ツリーを理解することは、そのような問題をデバッグするのに役立ちます。

Ready to learn this topic?

UI をツリーとして理解するを読んで、レンダーツリーやモジュール依存関係ツリーの作り方、そしてそのような考え方がユーザ体験やパフォーマンスを改善する際にどのように役立つのかについて学びましょう。

Read More

次のステップ

初めてのコンポーネントに進んで、この章をページごとに読み進めましょう!

もしくは、すでにこれらのトピックに詳しい場合、インタラクティビティの追加について読んでみましょう。