Further explanation of Svelte's keyed each block

I believe it uses something like the index of the item as the default when you do not provide a key. This can be validated by using

{#each things as thing, index (index)}
    <Thing current={thing.color}/>
{/each}

which gives the same behavior as not using a key in the first place.


Let's call the <Thing> that was rendered for id: 1 as Thing1, and so on.

With no key provided

When we remove the first item from the list, Thing1 still stays the same, because the key (index in this case) associated with it remains the same. The prop that was earlier being sent to Thing2 is now being sent to Thing1. This happens all the way down the chain. But now that there is one less element, Thing5 is removed from the DOM.

The instance of the component Thing that is associated with the key "0" (Thing1) is not destroyed when the first item is removed. This happens because the key stays the same (the new array also has an item at index 0). Only the prop that is being sent to Thing1 has changed, leaving the initial variable with the color of the original item with id: 1.

With (thing.id) key provided

When the thing with id: 1 is removed, there does not exist any instance of Thing which maps to "1". So, Thing1 is removed from the DOM.


Another way to understand is when you give a key, you are essentially telling Svelte to map each rendered block to that very key. When that key doesn't exist anymore, get rid of the block and remove it from the DOM. But if the key stays the same and the props change, update the props instead of recreating the block.

When you don't specify a key, it uses the index of the list as the key. So if you remove items from the list, it won't recreate or reorder the block, it will just update the props.

Tags:

Svelte 3