如何在SolidJS中维护列表项的激活状态?
在SolidJS中维护列表项激活状态的合理方案
问题原因
你遇到的问题是因为SolidJS的createStore采用结构共享优化,直接将store.items中的对象引用赋值给activeItem后,修改activeItem会通过引用篡改原数组内的对象,导致数组项被意外修改。
可行解决方案
1. 存储激活项的ID而非完整对象(推荐)
这是最简洁高效的方案,用唯一ID标识激活状态,完全避免引用问题:
const [store, setStore] = createStore({ items: [ { id: 1, name: "Apple" }, { id: 2, name: "Banana" } ], activeItemId: null // 仅存储ID }); // 切换激活项 setStore('activeItemId', 1); setStore('activeItemId', 2); // 获取当前激活项(可封装为计算属性) const activeItem = () => store.items.find(item => item.id === store.activeItemId);
2. 复制对象后存入activeItem
如果必须存储完整对象,每次赋值前浅拷贝对象切断引用:
// 切换时复制对象,避免引用关联 setStore('activeItem', {...store.items[0]}); setStore('activeItem', {...store.items[1]});
若对象存在嵌套属性,需使用深拷贝(如structuredClone):
setStore('activeItem', structuredClone(store.items[0]));
3. 用createSignal单独管理激活状态
如果激活状态无需和列表数据放在同一store,可使用独立的signal轻量化管理:
// 列表数据 const [items] = createSignal([ { id: 1, name: "Apple" }, { id: 2, name: "Banana" } ]); // 方式一:存ID const [activeItemId, setActiveItemId] = createSignal(null); const activeItem = () => items().find(item => item.id === activeItemId()); // 方式二:存复制后的对象 const [activeItem, setActiveItem] = createSignal(null); setActiveItem({...items()[0]});
内容的提问来源于stack exchange,提问作者Draex_
相关产品推荐
相关产品推荐

