---
title: correctness/each-key · キー付き each ブロック
description: 動的なデータを回す {#each} にはキーを付けましょう。
---

**重大度:** warning · **カテゴリ:** correctness

## チェック内容

キーのない `{#each}` ブロックを検出します。次の形は対象外とします。

- 定数のインライン配列リテラル（`{#each [1, 2, 3] as n}`）。長さが固定で並べ替えが起きないため、キーを付けても意味がありません。
- アイテムを取らない each（`{#each { length: 8 }, i}` という「N 回描画する」パターン）。キーを付けられるようなアイテムの同一性が存在せず、唯一付けられる index 自体をキーにしても無意味です。
- 長さのみのリスト（`Array(n)`、`[...Array(n)]`、`Array.from({ length: n })`）。順序に意味のない固定長のプレースホルダー/スケルトンリストであり、キーを付けても意味がありません。

## なぜ重要か

キーがないと、リストの並べ替えや要素の挿入、削除が起きたとき、Svelte は末尾でのノードの追加と削除で対応し、途中にある DOM ノードのデータを書き換えます。そのため要素の状態（フォーカス、入力、トランジション）がアイテムではなく位置に張り付いてしまい、余計な処理も発生します。キーがあれば、Svelte は正しいノードを挿入、移動、削除できます。

## 修正方法

```svelte
{#each items as item (item.id)}
  <li>{item.name}</li>
{/each}
```

## モードによる違い

ありません。このルールが読むのは同じ `.svelte` / `.ts` のソースファイルなので、CLI、Vite プラグインのビルド、ライブダッシュボードの静的ベースラインのいずれでも結果は同一で、レンダリング済み HTML の解析で再評価されることもありません。`--route` で実行範囲を絞ると、このルールは動きません。コンポーネントスコープのルールには、検出を紐づけるルートが無いためです。

## 無効化

個別に抑制するには、対象行の直前に `<!-- svelte-vitals-disable-next-line correctness/each-key -->` を置きます。ルールごと無効化するには、次のように設定します。

```js svelte-vitals.config.js
export default {
  rules: {
    'correctness/each-key': 'off'
  }
};
```
