Transfer组件动态更新数据后选中的项为什么会消失?
我在用Ant Design的Transfer组件时遇到问题,当通过接口动态更新源数据后,目标列表里之前选中的项会突然消失。比如用户已经把几个条目移到右边,这时候刷新数据源,右边的选中列表就空了。
我尝试给Transfer加了listKey属性,并确保dataSource的key是唯一的,但还是不行。这是我的代码片段:
<Transfer
listStyle={{ width: 200 }}
dataSource={data}
targetKeys={targetKeys}
onSelect={(keys, direction) => setSelected(keys)}
onChange={(nextKeys) => setTargetKeys(nextKeys)}
listKey={(item) => item.id.toString()}
/>
请问除了保留targetKeys状态之外,还需要做什么才能让动态更新数据时保留已选中的目标列表?是不是和key的设置有关?
targetKeys和dataSource的关联如果没有处理好,就会导致目标列表的状态丢失。你已经给
listKey设置了唯一标识,这一步是对的,但光靠这个还不够。关键是要保证dataSource和targetKeys的同步性。具体来说,当你动态更新dataSource时,新的数据源中必须包含当前targetKeys所对应的项,否则组件会认为这些项不存在,从而清空目标列表。解决办法是这样的:在更新
dataSource时,你需要同时检查并保留当前targetKeys中的有效项。假设你的data是从接口获取的新数据源,可以在更新时做一次过滤,确保targetKeys中的项仍然存在于新的dataSource中。这是我的解决方案代码:
简单解释一下这段代码的逻辑:
1. 每次从接口获取新数据后,先用
targetKeys对比新数据源,筛选出那些仍然存在的项。2. 把筛选后的结果重新赋值给
targetKeys,这样就能保证目标列表不会被清空。3. 最后再更新
dataSource和targetKeys。还有一点要注意,确保你的
id字段在整个数据流中是唯一的,并且和listKey的返回值保持一致。如果listKey返回的值不是id而是其他字段,记得调整对比逻辑。这样做之后,动态更新数据源时,目标列表的选中状态就不会丢了。我之前就是因为忽略了同步
targetKeys和dataSource的关系,调试了半天才找到问题所在,希望你能少走点弯路。targetKeys来管理目标列表的选中状态,但动态更新数据源时,Ant Design 的 Transfer 组件会重新渲染,如果数据源和targetKeys不完全匹配,就会导致目标列表被清空。建议改成这样处理:在动态更新数据源时,确保新的数据源不会影响到已经选中的
targetKeys。具体来说,你可以通过以下步骤解决:1. 在更新数据源时,检查新数据和旧数据的差异,只更新那些未被选中的项。
2. 确保
dataSource和targetKeys中的 key 值严格一致,比如你用的是item.id.toString(),那么整个流程都要统一使用这个规则。这里是一个改进后的代码示例:
重点是
updateDataSource方法,它会在更新数据源时保留已选中的项,而不是直接覆盖整个数据源。另外注意rowKey属性的设置,确保它的值和targetKeys的格式一致。最后吐槽一句,这种问题真是调试起来挺烦的,尤其是涉及到 React 的状态管理和组件渲染逻辑的时候,稍微不注意就容易踩坑。希望这个方案能帮你解决问题。