SolidJS中对象数组无响应:修改后DOM未更新如何解决?
问题原因
你修改的是原有todo对象的属性,虽然通过扩展运算符创建了新数组,但数组内的todo对象还是原来的引用。SolidJS的<For>组件默认通过引用识别列表项,认为引用未变的项没有更新,因此不会重新渲染对应的DOM元素——哪怕你已经修改了对象的属性值。
修复方案
不要直接修改原对象的属性,而是创建一个新的todo对象来替换原对象,这样数组内的项引用发生变化,<For>组件就能检测到更新并同步DOM。
修改后的代码:
import { render } from "solid-js/web"; import { createSignal, For } from "solid-js"; function ToDo() { const getToDos = () => { return [{ id: 1, name: 'one' }, { id: 2, name: 'two' }] } const onTodoClick = (id: number) => { // 直接基于旧数组映射,创建新对象替换目标项 setTodos(prevTodos => prevTodos.map(todo => todo.id === id ? { ...todo, name: `${todo.name} - Done` } : todo )); } const [todos, setTodos] = createSignal(getToDos()); return ( <div> <For each={todos()} > {(todo) => <p onClick={() => onTodoClick(todo.id)}>{todo.name}</p>} </For> </div> ); } render(() => <ToDo />, document.getElementById("app")!);
补充说明
这种写法的优势:
- 符合SolidJS的响应式追踪逻辑,通过值的变化(新对象引用)触发更新
- 保持数据不可变性,避免意外的副作用
- 代码更简洁,不需要手动复制数组、查找元素再修改
内容的提问来源于stack exchange,提问作者snippetkid
相关产品推荐
相关产品推荐

