【React】子コンポーネントを動的に指定する方法

【React】子コンポーネントを動的に指定する方法
スポンサーリンク

どうも、イソップです。

Reactアプリケーションでは、データをループ処理で一覧表示することが多いと思います。

その際によくあるのは、少しだけ違うコンポーネントが複数ある場合にループ用コンポーネントをたくさん作ってしまうこと
例えば、参照するデータは同じだけど、表示するコンポーネントの見ためがほんの少しだけ違うとか。

そういうケースが増えると、非常に管理が煩雑になりがちです。

そこで、今回はループ用の親コンポーネントを用意して、
その中のデータ表示用コンポーネントを親コンポーネントから指定できる方法を紹介します。

コンポーネントを用意

次のようなデータがあります。

const data = [ 'foo', 'bar', 'baz' ];

この表示用コンポーネントを用意します。

データを表示するだけの子コンポーネント

class ListItem extends Component {
  render() {
    return(
      <li>{this.props.text}</li>
    );
  }
}

アイコン付きの子コンポーネント

class IconListItem extends Component {
  render() {
    return(
      <li>
        <i className="icon"></i>
        <span>{this.props.text}</span>
      </li>
    );
  }
}

リスト表示するための親コンポーネント

import React, { Component } from 'react';
import ListItem from './ListItem';

class List extends Component {

  render() {

    const { data, component } = this.props;

    let ChildComponent = component || ListItem;

    return(
      <ul>
        {data.map((text, i) => {
          return React.createElement(ChildComponent, { key: i, text });
        })}
      </ul>
    );
  }
}

React.createElement() の部分が特に重要です。

React.createElement()

createElement はReactのコンポーネントを作成するAPIで、React.Componentを介さず自分でReactコンポーネントを作成することができます

React.createElement(
  type,
  [props],
  [...children]
)
  • type にはコンポーネント名か、クラスもしくは関数を渡すことができます。
  • props はプロパティをオブジェクトで渡します。
  • children はそのまま、コンポーネントのタグの中(<Hoge>...</Hoge>)のコンテンツが渡ります。

React Top-Level API #createElement

親に子コンポーネントを渡してあげる

createElement でコンポーネントを動的生成できるようにした List コンポーネントは、次のように使います。

const data = [ 'foo', 'bar', 'baz' ];

...

<List data={data} component={IconListItem} />

component プロパティに子コンポーネントを指定できるようにして、
List コンポーネントの種類違いを作らないようにしています。

component に何も指定しなければ、ListItem が使われます。

Listコンポーネント

const { data, component } = this.props;

let ChildComponent = component || ListItem;

React.createElement メソッドを活用することで、クリーンな設計にすることができます。

スポンサーリンク