Svelte中Table组件随prop变更不更新的问题如何解决?
问题根因
- 事件绑定错误:表头
th和单元格td的点击事件直接执行了回调函数而非绑定函数引用,导致组件渲染时就触发逻辑,点击时反而不会执行预期操作 - 违反单向数据流+原地修改数组:直接修改
things这个传入prop,且Array.sort是原地排序方法,不会生成新数组,Svelte无法检测到引用变更触发重渲染,还会意外污染父组件传入的原store数据 - 响应式逻辑错误:将
sort函数定义放在响应式标记$:下,会导致依赖变更时重复创建函数,产生不必要开销 - 边缘情况处理缺失:
colNames的响应式逻辑没有做空数组判断,things为空时会抛出报错,且仅在首项引用变更时才更新,适配性差
修复方案
第一步:修改Table.svelte组件逻辑
<script> import { createEventDispatcher } from "svelte"; export let things; export let title; export let note; const dispatch = createEventDispatcher(); function handleClick(thing, col) { dispatch("cellClick", { cell: thing, }); } // 空数组兼容,things变更时自动更新列名 $: colNames = things.length ? Object.keys(things[0]) : []; let sortBy = { col: "", ascending: true }; // 响应式排序:things或排序规则变更时自动生成新的排序后数组,不修改原prop $: sortedThings = (() => { // 未选择排序列时直接返回原数组拷贝 if (!sortBy.col) return [...things]; const sortModifier = sortBy.ascending ? 1 : -1; // 生成新数组排序,不修改原prop return [...things].sort((a, b) => a[sortBy.col] < b[sortBy.col] ? -1 * sortModifier : a[sortBy.col] > b[sortBy.col] ? 1 * sortModifier : 0 ); })(); // 普通函数定义,点击时修改排序规则触发自动重排 function handleSort(column) { if (sortBy.col == column) { sortBy.ascending = !sortBy.ascending; } else { sortBy.col = column; sortBy.ascending = true; } } </script> <div>{title}</div> <table> <thead> <tr> {#each colNames as col} <!-- 绑定点击回调而非直接执行函数 --> <th on:click={() => handleSort(col)}>{col} ↕</th> {/each} </tr> </thead> <tbody> <!-- 遍历排序后的本地数组,不直接使用prop,可加唯一key提升重渲染性能 --> {#each sortedThings as thing (thing.id)} <tr> {#each colNames as col} <td on:click={() => handleClick(thing, col)}>{thing[col]}</td> {/each} </tr> {/each} </tbody> </table> <div>{note}</div>
第二步:(可选)修正store更新逻辑
如果你的Firebase监听逻辑中是原地修改submissionsArr的内容(比如用push/splice等方法修改原数组),需要改为每次更新生成新数组赋值给store,示例:
// 错误写法:原地修改原数组 submissionsArr.update(oldArr => { oldArr.push(newItem); return oldArr; }) // 正确写法:返回新数组触发更新 submissionsArr.update(oldArr => [...oldArr, newItem])
修改后父组件不需要额外做$submissionsArr = $submissionsArr的强制更新操作,store变更会自动触发Table组件重渲染。
内容的提问来源于stack exchange,提问作者trubby22
相关产品推荐
相关产品推荐

