Skip to content

Feature request: Ability to key a non-each component #1469

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jacobmischka opened this issue May 15, 2018 · 11 comments · Fixed by #5397
Closed

Feature request: Ability to key a non-each component #1469

jacobmischka opened this issue May 15, 2018 · 11 comments · Fixed by #5397

Comments

@jacobmischka
Copy link
Contributor

It would be handy if we could force recreation of components sometimes, even if they're not within an each block.

For example, in react I could have used a key to workaround my issue in #1467 and force the component to remake itself from scratch and readd the defaults.

Thanks again!

@dodas
Copy link

dodas commented May 9, 2019

I would like to see this as well.
Meanwhile, we can workaround it using each: https://svelte.dev/repl/98b4af7d68594958b89d9fc9e069171c?version=3.2.2

<script>
let key = 1;

setInterval(() => {
  key++;
}, 1000);
</script>

{#each [key] as k (k)}
  <div>
    {Math.random()}
  </div>
{/each}

@jacobmischka
Copy link
Contributor Author

Ha oh duh, that's clever; wish I'd thought of that.

@Conduitry Conduitry added feature request awaiting submitter needs a reproduction, or clarification labels May 28, 2019
@stijnvanderlaan
Copy link

This would be nice! But great workaround!

@Conduitry
Copy link
Member

So it's not lost in Discord:

image

https://discordapp.com/channels/457912077277855764/506988048375087114/607596367577088035

@tivac
Copy link
Contributor

tivac commented Aug 8, 2019

{#key <id>}...{/key} is my strong preference for both back-compat and clarity.

@jacobmischka
Copy link
Contributor Author

Agreed, I think {#key} syntax would be perfect.

@rixo
Copy link
Contributor

rixo commented Nov 26, 2019

+1 for {#key}, I find it more aligned with Svelte principle of not requiring a unique root node.

Meanwhile, I wrapped the workaround into a component and published it as an npm package: https://github.com/rixo/svelte-key

@jesseskinner
Copy link
Contributor

I agree about {#key id}. I think this is really useful at times, and often lets you write much simpler components. The workaround with {#each [x] as x (x)} works but is inelegant. Using svelte-key is the best option we have at the moment but I'd rather it be built-in.

I'd be happy to take on the work of implementing if this proposal gets approved.

@PierBover
Copy link

This would be handy.

I've resorted to using a fake array with one element as @dodas suggested for a router I'm working on:

<script>
  import Route from 'router/Route.svelte';
  import {currentRoute} from 'router';

  let configArray;

  $: {
    configArray = [{
      key: Date.now(),
      components: $currentRoute.components
    }]
  }
</script>

{#each configArray as config (config.key)}
  <Route components={config.components}></Route>
{/each}

grizio pushed a commit to grizio/recepto that referenced this issue May 17, 2020
When changing page, but in the same component, the page was not refreshed.

There was these two issues:

* No transition
* Some part of the page is not updated

The reason was because Svelte reused the exact same component (so no mount / destroy and no animation on component creation / destruction).

To correctly update the page, we change the `Page` component by adding a keyed-each block (see sveltejs/svelte#1469).

There was some issue with this solution because each time we update the component, the render is updated so the Page and create an infinite loop.
To avoid this problem, we remove the call to `Page` component from concrete pages and include it directly with the Router. To do so, we create the PageRoute component behaving as expected.
@arafatamim
Copy link

I second this. Could be useful in animating list items outside an each block.

<div class="grid">
    {#each items as item, index (item.id)}
      <div animate:flip
        transition:fade
        class="grid-item"
        on:click={() => deleteItem(index)}
      >
      {item.value}
      </div>
    {/each}
    <button class="add-new" on:click={addItem}>
        Add item
    </button> <!-- Cannot apply animation to this element -->
</div>

@tanhauhau tanhauhau mentioned this issue Sep 15, 2020
4 tasks
@Conduitry
Copy link
Member

You can now do {#key expression}...{/key} in 3.28.0 - thanks @tanhauhau! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants