React公式ドキュメントを読む9 React要素とコンポーネント2

前回に引き続き、Reactのコンポーネントについて見ていきましょう。

コンポーネントからコンポーネントを呼び出せる

Reactでは、コンポーネントのなかから別のコンポーネントを呼び出せます。以下のサンプルでは、AppコンポーネントからWelcomeコンポーネント を3回呼び出しています。

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);

上記のサンプルソースをHTMLファイルにしたものが以下です。

https://programming-world.net/sample/react_component2-1.html

上記のサンプルが実行されると、画面には以下のように表示されます。

Hello, Sara
Hello, Cahal
Hello, Edite

AppコンポーネントがWelcomeコンポーネントを3回呼び出して、その都度name属性で名前を受け渡しています。名前を受け取った Welcomeコンポーネント は、「<h1>Hello, 受け取った名前</h1>」という戻り値を律儀に3回返しています。

ウェブページ内のパーツを分割しておくことで再利用性が高まる

コンポーネントのなかから別のコンポーネントを呼び出せるということは、コンポーネントを機能単位で分割しておけるということです。

ひとつのコンポーネントに機能を詰め込むと、コードが複雑になってしまうことがありますが、コンポーネントを分けてやるとシンプルさを保つことができます。

ウェブページ内のパーツを分割して個別のコンポーネントにしておくことで、コードがメンテナンスしやすくなり、コンポーネントを再利用しやすくなります。

シンプルでメンテナンスしやすいコードに

Reactでは、コンポーネントを扱いやすい機能単位で小さく分割することができます。行数の多いコードやネストが深いコードはメンテナンス性が悪くなりがちですが、コンポーネントを小さく分割することで複雑さが排除されてシンプルさが保たれます。

このことを実例で説明するために、React公式サイトでは以下の例が紹介されています。 以下のサンプルソース中のCommentコンポーネントは、いくつかの機能がひとつのコンポーネントにまとめられているため、ネストの深い複雑なコードになってしまっています。

//Commentコンポーネント は、機能が詰め込まれていて、ネストが深く複雑です
function Comment(props) {
  return (
    <div className="Comment">
      <div className="UserInfo">
        <img className="Avatar"
          src={props.author.avatarUrl}
          alt={props.author.name}
        />
        <div className="UserInfo-name">
          {props.author.name}
        </div>
      </div>
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

上記のコード中のCommentコンポーネントから、AvatarコンポーネントとUserInfoコンポーネントを抽出して分割したものが以下です。コンポーネントを分割することで、よりシンプルで読みやすいコードになっています。

//Avatarコンポーネントを抽出
function Avatar(props) {
  return (
    <img className="Avatar"
      src={props.user.avatarUrl}
      alt={props.user.name}
    />

  );
}

//UserInfoコンポーネントを抽出
function UserInfo(props) {
  return (
    <div className="UserInfo">
      <Avatar user={props.user} />
      <div className="UserInfo-name">
        {props.user.name}
      </div>
    </div>
  );
}

//Commentコンポーネントがシンプルに
function Comment(props) {
  return (
    <div className="Comment">
      <UserInfo user={props.author} />
      <div className="Comment-text">
        {props.text}
      </div>
      <div className="Comment-date">
        {formatDate(props.date)}
      </div>
    </div>
  );
}

上の2つのサンプルコードは、どちらも同じ動作をします。興味があれば、それぞれの画面を開いてソースを確認してみてください。

参考:上のサンプルの実行結果下のサンプルの実行結果

コンポーネントは小さく分割するべし

Reactでウェブアプリケーションを開発する場合、コンポーネントをどのくらいの単位に分割するのか迷うことがあるかもしれません。

例えば、ウェブページ内にユーザーのプロフィールを表示する部分があるとして、ユーザー紹介文とユーザーの画像を表示する部分をひとつのコンポーネントにまとめるべきか、それとも、分割して別のコンポーネントにしてしまうべきか…

このような迷いが生じた場合、一般的にはコンポーネントを小さく分割したほうがメリットが大きくなります。複雑なUIを作る場合ほどコンポーネントは小さく分割することをおすすめします。

複数の機能がまとめられたコンポーネントを、後から分解していくのは大変です。どちらかと言えば、小さなパーツから作っていって、より外側のパーツからそれらを呼び出すようにして全体を構築していく方が効率よく開発できます。

次回へ続きます。