Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

268
Visualizações
Svelte: state of components rendered with #each loop

Example and observed behaviour is here: Repl example

I have array of objects, each holding data that is passed to new component in #each loop. Seems like quite standard thing to have.

Each component has a button associated with its state variable, "isDescVisible", which says "show/hide more details". So far, so good. We click "show details" in "first" component, we get details of first component.

But then, we add one more object to data array. Still, pretty common thing to happen. And new component gets rendered. But somehow, state (displaying details or not) of all components (both old and new) is messed up. New component inherits state from old "top" one, and so on.

Question: why? second question: how to avoid that?

I could have imagined, that after mutating array, all components are destroyed and re-rendered. But in that case, we should have not see details displayed for any of those.

For those that don't want to go to repl, code below:

App.svelte:

<script>
import Entry from './Entry.svelte'
let base = [
    {title: 'First title', desc: 'First description'},
    {title: 'Second title', desc: 'Second description'}
]
function updateBase() {
    const newEntry = {title: 'Third title', desc: 'Third description'}
    base = [newEntry, ...base]
}
</script>

<button on:click={updateBase}>Add me!</button>

{#each base as entry}
<Entry {entry} />
{/each}



Entry.svelte:

<script>
export let entry
let isDescVisible = false


</script>

<p>
    {entry.title}
</p>
<button on:click={()=> isDescVisible = true}>
     Show Description
</button>
                
{#if isDescVisible}
<h2>
    I am visible! My description is {entry.desc}
</h2>
{/if}
about 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Give each item an ID and use it as the key in the #each block:

<script>
import Entry from './Entry.svelte'
let base = [
    {title: 'First title', desc: 'First description', id: 1},
    {title: 'Second title', desc: 'Second description', id: 2}
]
function updateBase() {
    const newEntry = {title: 'Third title', desc: 'Third description', id: 3}
    base = [newEntry, ...base]
}
</script>

<button on:click={updateBase}>Add me!</button>

<!-- The each loop uses the property in parentheses as the key -->
{#each base as entry (entry.id)}
<Entry {entry} />
{/each}

By providing a key, you are helping Svelte figure out which DOM node to change when base is updated. Without a key, Svelte will add and remove items at the end of the list by default, and then update any values that have changed. So we start with this...

  1. First title (open state)
  2. Second title

... and we add an item to the array, so we want this...

  1. Third title
  2. First title
  3. Second title

Without the key, Svelte doesn't know that we're adding an item to the front of the list. That's just one way to get to the final state. Another way (and the one Svelte defaults to) is to update (1)'s title to be "Third title", update (2)'s title to be "First title", and add a new item that has "Second title". Because (1) only has the props updated and is not recreated, it's internal open/closed state is preserved.

By adding a key, Svelte knows that the item at the front of the list is a new item, and will create a new node there instead of re-using the old one.

Tan Li Hau has a good visual explanation of this on Twitter.

tl;dr You should always provide a key in an #each loop if you are going to be modifying the list in any way.

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda