コンテンツにスキップ
svelte-vitals
日本語
Esc
移動開く⌘Jプレビュー
このページの内容

correctness/each-key · キー付き each ブロック

動的なデータを回す {#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 は正しいノードを挿入、移動、削除できます。

修正方法

{#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 --> を置きます。ルールごと無効化するには、次のように設定します。

export default {
  rules: {
    'correctness/each-key': 'off'
  }
};