ホーム

React.js で map() を使ってみる

古くなったIT技術にはご注意ください

リストとキー

まず、JavaScriptでリストをどのように変換するかを見てみましょう。以下のコードでは、map()関数を使用して数値の配列をとり、それらの値を2倍にします。 map()によって返された新しい配列を変数doubledに代入してログに記録します

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled);

このコードは [2,4,6,8,10] をコンソールに記録します。

複数のコンポーネントのレンダリング

要素のコレクションを作成し、中括弧{}を使用してJSXに含めることができます。以下では、Javascriptのmap()関数を使用してnumbers配列をループします。各アイテムに

要素を返します。最後に、結果の要素の配列をlistItemsに割り当てます。

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li>{number}</li>
);

listItems配列全体を<ul>要素の中に含め、それをDOMにレンダリングします。

ReactDOM.render(
  <ul>{listItems}</ul>,
  document.getElementById('root')
);

CodePenで試してみてください。

このコードは1から5までの数字の箇条書きリストを表示します。

基本リストコンポーネント

通常は、コンポーネントをリスト内にレンダリングします。数値の配列を受け取り、順序付けられていない要素のリストを出力するコンポーネントに、リファクタリングすることができます。

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li>{number}</li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

このコードを実行すると、リスト項目にキーを提供する必要があるという警告が表示されます。"キー"は、要素のリストを作成するときに含める必要がある特別な文字列属性です。次のセクションで重要な理由について説明します。numbers.map()`内のリスト項目にキーを割り当て、欠落しているキーの問題を修正しましょう。

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>

    //ここ
    <li key={number.toString()}>
      {number}
    </li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

CodePenで試してみてください。

Keys

キーは、どのアイテムが変更されたのか、追加されたのか、削除されたのかを識別します。要素に安定したアイデンティティを与えるために、配列内の要素にキーを与える必要があります。

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  //ここ
  <li key={number.toString()}>
    {number}
  </li>
);

キーを選択する最も良い方法は、兄弟間でリスト項目を一意に識別する文字列を使用することです。多くの場合、データのIDをキーとして使用します。

const todoItems = todos.map((todo) =>
  //ここ
  <li key={todo.id}>
    {todo.text}
  </li>
);

レンダリングされたアイテムのIDが安定していない場合は、アイテムインデックスを最後の手段としてキーとして使用できます。

const todoItems = todos.map((todo, index) =>
  // アイテムに安定したIDがない場合にのみ行う
  <li key={index}>
    {todo.text}
  </li>
);

項目の並べ替えが遅い場合、キーのインデックスを使用することはお勧めしません。あなたが興味を持っている場合、なぜキーが必要なのかについての詳細な説明を読むことができます。

キーによるコンポーネントの抽出

キーは、周囲の配列のコンテキストでのみ意味があります。

たとえば、ListItemコンポーネントを抽出する場合は、ListItem自体のルート

要素ではなく、配列の要素にキーを保持する必要があります。

例:不正なキーの使用

function ListItem(props) {
  const value = props.value;
  return (
    // 違う!ここでキーを指定する必要はありません。
    <li key={value.toString()}>
      {value}
    </li>
  );
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // 違う!キーはここで指定されているはずです:
    <ListItem value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

例:正しいキーの使用法

function ListItem(props) {
  // 正しい!ここでキーを指定する必要はありません。
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // 正しい!キーは配列内で指定する必要があります。
    <ListItem key={number.toString()}
              value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

CodePenで試してみてください。

経験則として、map()コールの中の要素にはキーが必要です。

キーは唯一の兄弟でなければならない

配列内で使用されるキーは、兄弟間で一意でなければなりません。しかし、それらは世界的にユニークである必要はありません。 2つの異なる配列を生成する場合、同じキーを使用できます。

function Blog(props) {
  const sidebar = (
    <ul>
      {props.posts.map((post) =>
        <li key={post.id}>
          {post.title}
        </li>
      )}
    </ul>
  );
  const content = props.posts.map((post) =>
    <div key={post.id}>
      <h3>{post.title}</h3>
      <p>{post.content}</p>
    </div>
  );
  return (
    <div>
      {sidebar}
      <hr />
      {content}
    </div>
  );
}

const posts = [
  {id: 1, title: 'Hello World', content: 'Welcome to learning React!'},
  {id: 2, title: 'Installation', content: 'You can install React from npm.'}
];
ReactDOM.render(
  <Blog posts={posts} />,
  document.getElementById('root')
);

CodePenで試してみてください。

キーはReactへのヒントとして機能しますが、コンポーネントに渡されることはありません。コンポーネントに同じ値が必要な場合は、別の名前のプロップとして明示的に渡します。

const content = posts.map((post) =>
  <Post
    key={post.id}
    id={post.id}
    title={post.title} />
);

上記の例では、Postコンポーネントはprops.idを読み取ることができますが、props.keyは読み取ることができません。

JSXにmap()を埋め込む

上記の例では、別のlistItems変数を宣言し、JSXにそれを含めました:

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <ListItem key={number.toString()}
              value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

JSXでは、任意の式を中括弧で埋め込むことができるので、map()の結果をインライン展開できます。

function NumberList(props) {
  const numbers = props.numbers;
  return (
    <ul>
      {numbers.map((number) =>
        <ListItem key={number.toString()}
                  value={number} />
      )}
    </ul>
  );
}

[CodePen](https://codepen.io/gaearon/pen/BLvYrB?editors=0010}で試してみてください。

場合によってはこれによりコードがより明確になることもありますが、このスタイルも悪用される可能性があります。 JavaScriptのように、可読性のために変数を抽出する価値があるかどうかを判断するのは、あなた次第です。 map()のボディがネストすぎると、コンポーネントを抽出するのがよいことに注意してください。

参考

Lists and Keys

Pocket
LinkedIn にシェア

エンジニアにおすすめできる本

Card image cap
リーダブルコード

より良いコードを書くためのシンプルで実践的なテクニック

Card image cap
Webを支える技術

HTTP,URI,HTML,そしてREST

Card image cap
誰でもPythonで作れる

儲かるAIとソフトウェアの作り方

Card image cap
プログラマが知るべき97のこと

現場で使える実践哲学のマスターピース

Card image cap
情熱プログラマー

時代を超えて。ソフトウェア開発者の幸せな生き方

Card image cap
アジャイルサムライ

プログラミング達人開発者への道

Card image cap
Rubyを作った男 まつもとゆきひろ

コードの世界 スーパー・プログラマになる14の思考法

ご提供 sponsor
 

Meee!(ミー)は、ビジネスからプライベート利用まで、個人のスキルを気軽に売り買いできるスキルマーケットです。カテゴリや居住地から、検索することが可能です。

 

ランゲージエクスチェンジは、ネイティブスピーカーと気軽にマッチングできる言語交換プラットフォームです。あなたの地元に住む外国人を探したり、留学や海外移住の前に、現地のネイティブスピーカーと繋がることもできます!

宣伝
 

りょすけトークchは、仕事や私生活をより豊にするYouTubeチャンネルです。文献(本、映画、論文)から役に立つ情報をまとめ、生涯にわたり役に立つ哲学をお届けしています。是非、チャンネル登録してみてね

-ホーム

Copyright© offブログ! , 2021 All Rights Reserved Powered by AFFINGER5.