How to animate an element on an inner change with Svelte?

Viewed 1931

Transitions in Svelte only apply to elements entering or exiting the DOM.

For example this would apply the fade when the div is initially added to the DOM:

<div in:fade>{message}</div>

How can we add a transition instead when message changes?

Since Svelte cannot have keys on single elements, the only solution I've found is to use a single element array to trigger a new element in the DOM whenever the array changes which doesn't seem ideal:

<script>
let messages = ['hello world'];

function updateMessages (message) {
    messages = [message];
}
</script>

{#each messages as message (message)}
    <div in:fade>{message}</div>
{/each}
2 Answers

As of Svelte 3.28, there is a {#key} that implements that functionality - see https://svelte.dev/docs#key

As an example this will cause the to run its transition whenever value changes.

{#key value}
    <div transition:fade>{value}</div>
{/key}

Your #each hack is indeed the recommended approach, currently (we may add something like a key directive in future, but no promises) — I'd just make one alteration, which is to do #each [x] as x rather than maintaining an array separately:

<script>
let message = 'hello world';

function updateMessages (new_message) {
    message = new_message;
}
</script>

{#each [message] as message (message)}
    <div in:fade>{message}</div>
{/each}
Related