fix(tutorial): improve explanation and example for Keyed Each Blocks

pull/5436/head
vwkd 5 years ago
parent 6c8bd6e5aa
commit 4be902b930

@ -1,23 +1,23 @@
<script>
import Thing from './Thing.svelte';
let things = [
{ id: 1, color: '#0d0887' },
{ id: 2, color: '#6a00a8' },
{ id: 3, color: '#b12a90' },
{ id: 4, color: '#e16462' },
{ id: 5, color: '#fca636' }
let array = [
{ id: 1, data: 1 },
{ id: 2, data: 2 },
{ id: 3, data: 3 },
{ id: 4, data: 4 },
{ id: 5, data: 5 }
];
function handleClick() {
things = things.slice(1);
array = array.slice(1);
}
</script>
<button on:click={handleClick}>
Remove first thing
Remove first element
</button>
{#each things as thing}
<Thing current={thing.color}/>
{#each array as element}
<Thing current={element.data}/>
{/each}

@ -6,19 +6,14 @@
const initial = current;
</script>
<p>
<span style="background-color: {initial}">initial</span>
<span style="background-color: {current}">current</span>
</p>
<p>initial: {initial}, current: {current}</p>
<style>
span {
display: inline-block;
padding: 0.2em 0.5em;
margin: 0 0.2em 0.2em 0;
width: 4em;
p {
background-color: #ededed;
padding: 0.5em 0;
margin: 1em 0;
text-align: center;
border-radius: 0.2em;
color: white;
}
</style>

@ -1,23 +1,23 @@
<script>
import Thing from './Thing.svelte';
let things = [
{ id: 1, color: '#0d0887' },
{ id: 2, color: '#6a00a8' },
{ id: 3, color: '#b12a90' },
{ id: 4, color: '#e16462' },
{ id: 5, color: '#fca636' }
let array = [
{ id: 1, data: 1 },
{ id: 2, data: 2 },
{ id: 3, data: 3 },
{ id: 4, data: 4 },
{ id: 5, data: 5 }
];
function handleClick() {
things = things.slice(1);
array = array.slice(1);
}
</script>
<button on:click={handleClick}>
Remove first thing
Remove first element
</button>
{#each things as thing (thing.id)}
<Thing current={thing.color}/>
{#each array as element (element.id)}
<Thing current={element.data}/>
{/each}

@ -6,19 +6,14 @@
const initial = current;
</script>
<p>
<span style="background-color: {initial}">initial</span>
<span style="background-color: {current}">current</span>
</p>
<p>initial: {initial}, current: {current}</p>
<style>
span {
display: inline-block;
padding: 0.2em 0.5em;
margin: 0 0.2em 0.2em 0;
width: 4em;
p {
background-color: #ededed;
padding: 0.5em 0;
margin: 1em 0;
text-align: center;
border-radius: 0.2em;
color: white;
}
</style>

@ -2,18 +2,20 @@
title: Keyed each blocks
---
By default, when you modify the value of an `each` block, it will add and remove items at the *end* of the block, and update any values that have changed. That might not be what you want.
By default, when you add / remove an item from the iterable that the `each` block iterates over, it will add / remove the component instance at the *end* of the block instead of the corresponding instance. If you add / remove items from anywhere other than the end of the iterable, this leads to each component instance corresponding to a different element of the iterable than the one it was first created for. This might not be what you want.
It's easier to show why than to explain. Click the 'Remove first thing' button a few times, and notice that it's removing `<Thing>` components from the end and updating the `color` for those that remain. Instead, we'd like to remove the first `<Thing>` component and leave the rest unaffected.
It's easier to understand with an example. For each element of the array, <code>#each</code> creates one instance of the `<Thing>` component seen as a row. The initial value shows to which element of the original array the instance corresponded when it was created, while the current value shows which element of the current array it corresponds to now. The expected behavior would be that both values match.
To do that, we specify a unique identifier for the `each` block:
Click the 'Remove first element' button a few times, and notice that it's removing `<Thing>` components from the end, and updating the value for those that remain. Instead, we'd like to remove the first `<Thing>` component and leave the rest unaffected.
To do that, we specify a unique identifier for the `each` block in parentheses:
```html
{#each things as thing (thing.id)}
<Thing current={thing.color}/>
{#each array as element (element.id)}
<Thing current={element.id}/>
{/each}
```
The `(thing.id)` tells Svelte how to figure out what changed.
The `(element.id)` tells Svelte how to figure out what changed.
> You can use any object as the key, as Svelte uses a `Map` internally — in other words you could do `(thing)` instead of `(thing.id)`. Using a string or number is generally safer, however, since it means identity persists without referential equality, for example when updating with fresh data from an API server.
> You can use any object as the key, as Svelte uses a `Map` internally — in other words you could do `(element)` instead of `(element.id)`. Using a string or number is generally safer, however, since it means identity persists without referential equality, for example when updating with fresh data from an API server.

Loading…
Cancel
Save