Svelte中父组件表格取消选择后,子组件isSelected未更新如何解决?
解决Svelte组件选中状态不同步问题
当你从table#selection中取消选中Block时,Block组件内的isSelected变量未更新,核心原因是子组件维护了独立的选中状态,与父组件的选择状态产生了数据不一致:
- 父组件List通过
isSelectedprop传递选中状态给Block - 但Block组件内部在点击按钮时直接修改了本地的
isSelected变量,打破了父子组件间的单向数据流绑定 - 当父组件通过表格删除选中项时,子组件的本地状态无法同步更新
修复方案:统一状态管理,让父组件作为唯一数据源
1. 修改Block.svelte,移除本地状态依赖
删除Block组件内的本地isSelected状态修改逻辑,完全依赖父组件传递的prop,点击按钮时仅触发事件交由父组件处理状态变更:
<script> import {createEventDispatcher} from "svelte"; export let block; export let isSelected = false; // 仅作为prop接收,不再本地修改 const dispatch = createEventDispatcher(); function toggleSelection(block) { dispatch('toggleSelection', { block }); // 移除本地修改isSelected的代码,状态变更统一由父组件处理 } </script> <div> {block.title} <button on:click={() => toggleSelection(block)}> {#if isSelected} Remove from selection {:else} Add to selection {/if} </button> </div>
2. 确保父组件状态变更同步到子组件
父组件List的selection对象维护逻辑本身是正确的:删除选中项时通过对象解构创建新的selection对象,Svelte会自动检测到状态变更。由于我们不再在子组件中覆盖isSelected prop,父组件的状态更新会直接同步到Block组件,按钮文本和选中状态会自动修正。
额外优化(可选):简化父组件判断逻辑
可以将isBlockSelected函数替换为模板内直接判断,让逻辑更直观:
在List.svelte的#each循环中,将isSelected={isBlockSelected(block)}改为:
<Block {block} on:toggleSelection={handleToggleSelection} isSelected={!!selection[block.id]}/>
同时可以删除父组件中isBlockSelected函数的定义,效果完全一致。
内容的提问来源于stack exchange,提问作者Seglinglin
相关产品推荐
相关产品推荐

