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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 00:45:02