zukucode
主にWEB関連の情報を技術メモとして発信しています。

Reactのリスト表示でkeyに安定したIDを使う

Reactで配列を表示するとき、各要素にkeyを付けます。これは表示する項目を再描画の前後で対応付けるための目印です。

IDをkeyにする

type Item = { id: string; name: string };

const ItemList = ({ items }: { items: Item[] }) => (
  <ul>
    {items.map((item) => (
      <li key={item.id}>{item.name}</li>
    ))}
  </ul>
);

keyは同じ一覧の兄弟要素の間で一意であればよく、データ全体で一意である必要はありません。

indexが問題になる場面

並べ替えや途中への追加・削除がある一覧で配列の位置をkeyにすると、位置が変わった別の項目を同じ要素と見なすことがあります。入力欄の値やコンポーネントの状態が、意図しない行へ残る原因になります。

// 並びが変わる一覧では避ける
{items.map((item, index) => <li key={index}>{item.name}</li>)}

順序も件数も変わらない固定の一覧ならindexで問題にならない場合もあります。通常はデータが持つ安定したIDを選びます。描画中にcrypto.randomUUID()で毎回新しいkeyを作るのも避けてください。

入力欄で違いを確認する

各行に入力欄があるリストで先頭の行を削除し、残った入力欄の値を確認してみてください。indexをkeyにすると、Reactは「以前の0番目」と「現在の0番目」を同じ行として扱い、入力状態を別の項目へ引き継ぐことがあります。IDをkeyにすれば、項目の移動後も同じIDの行として対応付けられます。

keyは子コンポーネントの通常のpropsとしては渡されません。子でIDを使うなら、<ItemRow key={item.id} id={item.id} />のように別のpropsでも渡します。


関連記事

  • TypeScript i18nextの動的な翻訳キーを抽出対象に含める

    i18nextでステータスに応じた文言を表示する場合、翻訳キーを動的に切り替えることがあります。ただし、実行時に正しく表示できることと、翻訳キーの抽出ツールが使用箇所を検出できることは別です。今回は、...


  • React useStateで入力フォームを作成する

    Reactでテキストボックスに入力した値を使用するには、useStateで値を保持します。今回は名前とメールアドレスを入力し、送信ボタンを押すと入力内容を表示するフォームを作成します。この例では入力値...


  • React useStateで一覧の追加と削除を行う

    Reactで一覧を表示するときは、配列をuseStateへ保存できます。今回は簡単な買い物リストを作り、項目の追加と削除を行います。配列のpushやspliceで既存のstateを直接変更するのではな...


  • React useEffectで無限ループが発生するときに確認すること

    ReactのuseEffectを利用したときに無限ループが発生してしまうことがあります。特に注意したいのが、ESLintのreact-hooks/exhaustive-depsで表示された警告をUpd...


  • React useEffectの後片付けでイベント登録を解除する

    画面の幅が変わったときに表示を更新したい場合、ブラウザのresizeイベントを登録できます。登録したままにすると、コンポーネントが不要になったあとも処理が残るため、useEffectの後片付けを用意し...


  • React 関数コンポーネントにプロパティを設定する

    React+TypeScriptで作成した関数コンポーネントにプロパティを設定する方法を紹介します。以下は送信ボタンのコンポーネントを作成しています。isSubmittingというプロパティを用意して...


  • Reactで兄弟コンポーネントの状態を共有する

    検索欄に入力した文字列を、別の一覧コンポーネントでも使いたい場合があります。兄弟同士で別々にstateを持つと値がずれるため、共通の親にstateを置きます。入力欄は値を受け取り、変更を親へ通知します...


  • React useStateでselectの選択値を取得する

    Reactでプルダウンの選択値を扱うには、selectのvalueとonChangeを使用します。DOMから取得するvalueは、数値の選択肢を表示していても文字列です。選択値をそのまま識別子として扱...


  • React react-router-domの基本的な使い方

    React+TypeScriptのプロジェクトにreact-router-domを導入してSPAのアプリケーションを作成する方法を紹介します。まずはreact-router-domのパッケージをインス...


  • react-router-dom ページごとにファイルを分割する

    react-router-domでシングルアプリケーションを作成していると、ページ数が増えるにしたがって作成されるjsファイルのファイルサイズもどんどん増えていきます。ページごとにファイルを分割し、そ...