Props を使用したデータの表示

これまでのところ、<Header /> コンポーネントを再利用しても、同じ内容が2回表示されます。

index.html
function Header() {
  return <h1>Develop. Preview. Ship.</h1>;
}
 
function HomePage() {
  return (
    <div>
      <Header />
      <Header />
    </div>
  );
}

しかし、異なるテキストを渡したい場合や、外部ソースからデータを取得しているため事前に情報がわからない場合はどうすればよいでしょうか?

通常のHTML要素には、その要素の動作を変更する情報を渡すための属性があります。例えば、<img>要素のsrc属性を変更すると、表示される画像が変わります。<a>タグのhref属性を変更すると、リンクの目的地が変わります。

同じように、Reactコンポーネントにも情報の断片をプロパティとして渡すことができます。これらはpropsと呼ばれます。例えば、ボタンのバリエーションを考えてみましょう:

ボタンコンポーネントの3つのバリエーションを示す図: Primary、Secondary、Disabled

JavaScriptの関数と同様に、カスタム引数(またはprops)を受け入れるコンポーネントを設計できます。これにより、コンポーネントの動作や画面に表示される内容を変更できます。そして、これらのpropsを親コンポーネントから子コンポーネントに渡すことができます。

注: Reactでは、データはコンポーネントツリーを下に流れます。これは_一方向データフロー_と呼ばれます。次の章で説明するstateは、propsとして親から子コンポーネントに渡すことができます。

propsの使用

HomePageコンポーネントでは、HTML属性を渡すのと同じように、Headerコンポーネントにカスタムtitleプロパティを渡すことができます:

index.html
function HomePage() {
  return (
    <div>
      <Header title="React" />
    </div>
  );
}

そして、子コンポーネントであるHeaderは、これらのpropsを最初の関数パラメータとして受け取ることができます:

index.html
function Header(props) {
  return <h1>Develop. Preview. Ship.</h1>;
}

console.log()でpropsを表示すると、titleプロパティを持つオブジェクトであることがわかります。

index.html
function Header(props) {
  console.log(props); // { title: "React" }
  return <h1>Develop. Preview. Ship.</h1>;
}

propsはオブジェクトなので、関数パラメータ内でpropsの値を明示的に名前付けするためにオブジェクト分割代入を使用できます:

index.html
function Header({ title }) {
  console.log(title); // "React"
  return <h1>Develop. Preview. Ship.</h1>;
}

そして、<h1>タグの内容をtitle変数に置き換えることができます。

index.html
function Header({ title }) {
  console.log(title);
  return <h1>title</h1>;
}

ブラウザでファイルを開くと、実際に「title」という単語が表示されていることがわかります。これは、Reactがプレーンテキスト文字列をDOMにレンダリングしようとしていると解釈するためです。

JavaScript変数であることをReactに伝える方法が必要です。

JSXでの変数の使用

titleプロパティを使用するには、中括弧 {}を追加します。これは、JSXマークアップ内で直接通常のJavaScriptを記述できる特別なJSX構文です。

index.html
function Header({ title }) {
  console.log(title);
  return <h1>{title}</h1>;
}

中括弧は、「JSXの世界」にいながら「JavaScriptの世界」に入る方法と考えることができます。中括弧内に任意のJavaScript式(単一の値に評価されるもの)を追加できます。例えば:

  1. オブジェクトプロパティとドット記法:
example.js
function Header(props) {
  return <h1>{props.title}</h1>;
}
  1. テンプレートリテラル:
example.js
function Header({ title }) {
  return <h1>{`Cool ${title}`}</h1>;
}
  1. 関数の戻り値:
example.js
function createTitle(title) {
  if (title) {
    return title;
  } else {
    return 'Default title';
  }
}
 
function Header({ title }) {
  return <h1>{createTitle(title)}</h1>;
}
  1. または三項演算子:
example.js
function Header({ title }) {
  return <h1>{title ? title : 'Default Title'}</h1>;
}

これで、任意の文字列をtitleプロパティに渡すことができます。三項演算子を使用した場合、titleプロパティをまったく渡さないこともできます。コンポーネントでデフォルトケースを考慮しているためです:

example.js
function Header({ title }) {
  return <h1>{title ? title : 'Default title'}</h1>;
}
 
function HomePage() {
  return (
    <div>
      <Header />
    </div>
  );
}

これで、コンポーネントは汎用的なtitleプロパティを受け入れるようになり、アプリケーションのさまざまな部分で再利用できます。必要なのは、title文字列を変更することだけです:

index.html
function HomePage() {
  return (
    <div>
      <Header title="React" />
      <Header title="A new title" />
    </div>
  );
}

リストの反復処理

リストとして表示する必要があるデータを持つことは一般的です。配列メソッドを使用してデータを操作し、スタイルは同じだが異なる情報を含むUI要素を生成できます。

HomePageコンポーネントに次の名前の配列を追加します:

index.html
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li>{name}</li>
        ))}
      </ul>
    </div>
  );
}

そして、array.map()メソッドを使用して配列を反復処理し、アロー関数を使用して名前をリストアイテムにマッピングできます:

index.html
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li>{name}</li>
        ))}
      </ul>
    </div>
  );
}

「JavaScript」と「JSX」の世界を行き来するために中括弧を使用した方法に注目してください。

このコードを実行すると、Reactはkeyプロパティが欠落していることについて警告を表示します。これは、Reactが配列内のアイテムを一意に識別するものが必要であり、DOM内で更新する要素を知る必要があるためです。

今のところ名前を使用できます(現在は一意であるため)が、アイテムIDなど、一意であることが保証されているものを使用することをお勧めします。

index.html
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li key={name}>{name}</li>
        ))}
      </ul>
    </div>
  );
}

追加リソース:

On this page