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

如何在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_

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 05:06:06