【実務・中級編】 リストレンダリングとkeyプロパティの重要性 – React実践ガイド

なぜReactの「key」はあなたの人生を救うのか?リストレンダリングの深淵

現場でコードを書いていると、「とりあえず `map` で回して `key` に `index` 入れておけば動くでしょ」という場面に出くわすことがよくある。正直に言おう、それは「地雷を埋め込んでいるのと同義」だ。

今回は、Reactのリストレンダリングにおける「key」の真の役割と、差分検出アルゴリズム(Reconciliation)の裏側について、中級者の一歩先を行く視点で深掘りしていく。

—

1. 仮想DOMと「差分検出」という名の職人芸

Reactが高速なのは、DOMを直接いじらないから……というのは半分正解で半分は誤解だ。真髄は、「最小限のDOM操作で済むように、賢く差分を見抜くアルゴリズム」にある。

Reactは `render` のたびに新しい仮想DOMツリーを構築し、前のツリーと比較する。この「差分検出(Diffing)」において、リストのような動的な要素を扱うとき、Reactは非常に困る。
「このリストの3番目の要素が削除されたとき、残りの要素が移動したのか、それとも中身が書き換わっただけなのか?」
これを人間がパッと見てわかるように、Reactに教えるためのIDタグ、それが `key` だ。

—

2. なぜ「index」をkeyにしてはいけないのか?

これ、新人研修でよく見る光景だが、配列のインデックス(`index`)を `key` にするのはアンチパターンだ。

もしリストの先頭に要素を追加した場合、インデックスはすべてズレる。Reactは「あ、全部の要素が入れ替わったんだな」と勘違いし、DOMを再生成する。これではせっかくの仮想DOMの恩恵が台無しだし、もっと深刻なのはコンポーネントの内部状態(State)が壊れることだ。

例えば、入力フォームがあるリストでインデックスをkeyにすると、削除や追加をした瞬間に、前の行の入力内容が次の行に引き継がれるというバグが発生する。これはReactのせいではない。我々が「識別子」を正しく渡さなかったせいだ。

—

3. 実務で使うべき「正しいリストレンダリング」

現場では、「永続的な一意のID」をバックエンドから受け取ることが鉄則だ。もし存在しないなら、フロントエンド側で生成するのではなく、データ構造そのものを見直す勇気を持ってほしい。

以下に、実務で使える「再利用可能なリストコンポーネント」の構成例を示す。

import React from ‘react’;

/

  • 実務レベルのリストレンダリング例
  • ポイント:keyにはindexではなく、データ固有のidを使用する

/
const UserList = ({ users }) => {
return (

    {users.map((user) => (

  • ))}

);
};

// コンポーネントを分割することで、Reactはkeyごとに
// どのコンポーネントが更新されたかをより正確に追跡できる
const UserItem = ({ name }) => {
// ここで独自のStateや副作用を持つ場合でも、
// keyが正しければ状態の不整合は起きない
return {name};
};

export default UserList;

このコードの「賢い」ところ

  • keyの安定性: `user.id` はデータが削除されない限り不変だ。ReactはDOMツリーの移動を正確にトレースできる。
  • 関心の分離: `UserItem` に責務を分離することで、リスト全体を再レンダリングせず、変更のあった行だけをピンポイントで更新させる「メモ化(React.memo)」の土台を作っている。

—

4. シニアからのアドバイス:現場での判断基準

最後に、現場で迷った時の判断指針を伝えておく。

1. データにIDがない場合:

  • APIのレスポンスが悪いなら、バックエンドチームと相談してIDを追加してもらうのが一番の近道だ。
  • どうしても無理なら、データ生成時に `crypto.randomUUID()` 等で一時IDを付与するが、これは最後の手段だ。

2. 静的なリスト(並び替えが絶対に発生しない)なら:

  • 例外的に `index` を許容することもある。だが、コードレビューで「なぜここで `index` を使ったか」を論理的に説明できないなら、最初から書かない方が身のためだ。

3. パフォーマンスの罠:

  • `key` に `Math.random()` を使うのは絶対NGだ。レンダリングのたびにkeyが変わり、リスト全体が毎回再構築されるため、パフォーマンスは最悪になる。

—

まとめ:Reactは「正直」に振る舞え

Reactは、君たちが思っている以上に「正直」なライブラリだ。君たちが正しい情報を与えれば、驚くほど効率的に仕事をしてくれる。逆に、適当な情報を与えれば、その「嘘」のツケをパフォーマンス低下やバグという形で返してくる。

`key` を正しく選ぶことは、ただの技術的なお作法じゃない。「このデータはこれである」という設計者の意志を、Reactに正しく伝えるコミュニケーションなんだ。

明日からのコードレビューでは、ぜひ `key={index}` という記述を見つけたら、「なぜこれが必要なのか?」「本当にこれで将来的な要件変更に耐えられるのか?」をチームで議論してみてほしい。そこから、君たちのプロダクトは一段階上のクオリティへ進化するはずだ。

コメント

タイトルとURLをコピーしました