I’m working on some code where I fetch some items in onMount then render them. I don’t want to play a ton of transitions for the big batch of fetched items. However, I do want to play transitions when individual items are added or removed from the list. This is a similar situation to this question.
If I write this, then I get the transition behavior I want.
{#if itemsFetched}
{#each items as it (it.id)}
<div transition:slide|local>
<span>{it.id} {it.name}</span>
<button on:click={removeItem(it)}>remove</button>
</div>
{/each}
{/if}
However, inside of the each block, I need to conditionally render something.
And if I add an if block, then the individual item transitions don’t play at all.
{#if itemsFetched}
{#each items as it (it.id)}
{#if it.id >= 0}
<div transition:slide|local>
<span>{it.id} {it.name}</span>
<button on:click={removeItem(it)}>remove</button>
</div>
{/if}
{/each}
{/if}
Here’s a full example.
Sandbox: https://codesandbox.io/s/sleepy-pasteur-st68wb?file=/App.svelte
<script>
import { slide } from "svelte/transition";
import { onMount } from "svelte";
// Initially we have no items.
let items = [];
let id = 0;
let itemsFetched = false;
onMount(() => {
// Fetch items from API.
items = [
{id: id, name: `item ${id++}`},
{id: id, name: `item ${id++}`},
{id: id, name: `item ${id++}`},
];
itemsFetched = true;
});
function addItem() {
items = [
...items,
{id: id, name: `item ${id++}`},
];
}
function removeItem(rmIt) {
return () => {
items = items.filter(it => it.id !== rmIt.id);
};
}
</script>
<div>
<button on:click={addItem}>add</button>
{#if itemsFetched}
{#each items as it (it.id)}
{#if it.id >= 0}
<div transition:slide|local>
<span>{it.id} {it.name}</span>
<button on:click={removeItem(it)}>remove</button>
</div>
{/if}
{/each}
{/if}
</div>
Why does adding an if block break the local transition? If I remove local, then the items play transitions when added or removed, but then I lose the initial onMount behavior I want.