🎩

ゼロから学ぶ React, Next.js④【React Foundations】Chapter6

2024/05/24に公開

公式チュートリアルはこちら
https://nextjs.org/learn/react-foundations/displaying-data-with-props

【Chapter】 Props でデータを表示する

これまでのところ、<Header /> コンポーネントを再利用すると、両方の場所で同じコンテンツが表示されます。

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

function HomePage() {
  return (
    <div>
+      <Header />
+      <Header />
    </div>
  );
}

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

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

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

props

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

props の使用

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

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>;
}
メモ:オブジェクトの分割代入

リンクにも説明がありますが、今回のコードの例で言うと、props オブジェクトから title プロパティを取り出して、title という変数に代入しています。以下の{title}Headerコンポートの引数として渡しています。

const props = { title: "React" };
// オブジェクトの分割代入 以下のような形式で取得できる
const { title } = props;
console.log(title); // "React"

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

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

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

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


JSX での変数の使用

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

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

中括弧は、"JSX国" にいる間に言語の異なる "JavaScript国"の言語であるJavaScriptが使える方法の一つです(意訳)。中括弧内には、任意の JavaScript 式(単一の値に評価されるもの)を追加できます。例えば、以下のようなものがあります。

  1. ドット記法を使用したオブジェクトプロパティ:
function Header(props) {
  return <h1>{props.title}</h1>;
}
  1. テンプレートリテラル:
function Header({ title }) {
  return <h1>{`Cool ${title}`}</h1>;
}
  1. 関数の戻り値:
function createTitle(title) {
  if (title) {
    return title;
  } else {
    return 'Default title';
  }
}

function Header({ title }) {
  return <h1>{createTitle(title)}</h1>;
}
  1. 三項演算子:
function Header({ title }) {
  return <h1>{title ? title : 'Default Title'}</h1>;
}
メモ:三項演算子

条件に続いて疑問符 (?)、そして条件がTrueであった場合に実行する式、コロン (:) が続き、条件がFalseであった場合に実行する式が最後に来ます。この演算子は、 if 文の代替としてよく用いられます。→詳細

条件 ? 条件がTrueの場合 : 条件がFalseの場合

これで、任意の文字列を title prop に渡すことができます。あるいは、三項演算子を使用した場合は、コンポーネント内でデフォルトのケースを考慮しているので、title prop を渡さなくてもかまいません。

index.html
function Header({ title }) {
+  return <h1>{title ? title : 'Default title'}</h1>;
}

function HomePage() {
  return (
    <div>
      <Header />
    </div>
  );
}

コンポーネントは汎用的な title prop を受け入れるようになったので、アプリケーションのさまざまな部分で再利用できます。必要なのは、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 prop がないことについて警告を出します。これは、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>
  );
}

追加のリソース


次の章

https://zenn.dev/gunjo/articles/51d0a2d22f84f1

Discussion