You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Svelte {#each}迭代翻倍及绑定删除时报Cannot set properties of undefined错误

问题成因解析

1. {#each}迭代次数为预期值两倍的成因

  • 最常见原因是当前使用SvelteKit或其他带服务端渲染(SSR)的开发环境:服务端会先执行一次{#each}逻辑生成初始DOM,客户端水合阶段会再执行一次渲染逻辑,最终呈现出迭代次数翻倍的现象,生产环境关闭SSR后该问题会自动消失。
  • 次要原因是{#each}未指定唯一key值:Svelte默认使用数组索引作为迭代项的身份标识,当数组发生变更或绑定变量触发不必要重渲染时,内部diff逻辑可能误判生成重复节点。

2. 点击删除抛出"Cannot set properties of undefined"错误的成因

该错误由代码中的多处关联问题共同导致:

  • 变量声明不符合响应式要求:你用const声明了foodList,但后续通过foodList = foodList重新赋值触发响应式的操作违反了const不可重赋值的规则,会直接抛出赋值异常,连带影响后续绑定逻辑执行。
  • 绑定目标错误:你在{#each}中解构了每个数组项的elem字段,但bind:this却绑定了未声明的elems[index]变量,elems本身为undefined,绑定时尝试给undefined的对应索引属性赋值,直接触发报错。
  • 事件传参错误:你写的on:click={remove}会把点击事件对象作为参数传给remove函数,而非当前迭代项的索引,splice(事件对象, 1)执行逻辑完全不符合预期,会导致数组长度异常变更。
  • 无唯一key导致绑定错乱:即使修复上述问题,未给{#each}指定唯一key的情况下,删除某一项后后续所有项的索引都会前移,Svelte更新bind:this绑定时会尝试访问已经被删除的索引位置的变量,同样会抛出属性设置错误。

修复后可运行的参考代码

<script>
    // 改为let声明支持重赋值触发响应式
    let foodList = [
      // 新增id作为唯一key
      { id: 1, icon: '🍲', elem: null, },
      { id: 2, icon: '🥫', elem: null, },
      { id: 3, icon: '🍔', elem: null, },
    ]; 
    const remove = (index) => { 
      foodList.splice(index, 1);
      foodList = foodList;
    };
</script>

<!-- 新增key,绑定到当前项的elem属性,点击时传入index -->
{#each foodList as {id, icon, elem}, index (id)}
  <div 
    bind:this={elem}
    on:click={() => remove(index)}
  >
    {icon}
  </div>
{/each}

内容的提问来源于stack exchange,提问作者Mero

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 01:15:08