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'
}
};