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

SolidJS技术疑问:如何让DOM元素响应Signal更新?

解决SolidJS中Signal更新不触发DOM响应的问题

问题1:Origin Component中计数不更新

原因

你直接修改了Signal返回的原数组(init.push/init.splice),随后又把同一个数组引用传给setItems。SolidJS的Signal默认采用引用相等性检查,当传入的新值与旧值是同一个引用时,不会触发更新逻辑。

修复代码

创建数组的全新副本,避免修改原引用:

import { Component, createSignal } from 'solid-js'
import { isEqual as _isEqual } from 'lodash-es'

const [getItems, setItems] = createSignal<Array<Item>>([])

const OriginComponent: Component = () => {
    const updateItems = (item: Item) => {
        const currentItems = getItems()
        const index = currentItems.findIndex(i => _isEqual(i, item))

        // 创建新数组副本,不修改原数组
        const newItems = index === -1 
            ? [...currentItems, item] 
            : currentItems.filter((_, idx) => idx !== index)

        setItems(newItems)
    }

    return (
        <>
            <span>Item Count: {getItems().length}</span>
            <button onClick={() => updateItems(/* 传入正确的Item实例 */)}>Click Me</button>
        </>
    )
}

export { OriginComponent, getItems }

注意:SolidJS中事件处理需要用驼峰式命名(onClick),而非原生DOM的onclick。

问题2:Remote Component中状态不更新

原因

核心问题还是Origin Component中Signal未正确触发更新,只要Origin里的Signal使用新引用更新后,RemoteComponent中的getItems()需要处于SolidJS的响应式跟踪上下文里,才能自动感知变化。

修复代码

确保getItems()在组件的响应式上下文中调用,可用createMemo优化状态判断:

import { Component, createMemo } from 'solid-js'
import { getItems } from '../OriginComponent'

const RemoteComponent: Component = () => {
    // 用createMemo缓存判断结果,避免重复计算
    const hasItems = createMemo(() => getItems().length > 0)
    
    return (
        <p class='results'>
            {hasItems() ? 'Has Items' : 'Has No Items'}
        </p>
    )
}

关键要点总结

  • SolidJS的Signal依赖值的变化(默认是引用相等)触发更新,更新数组/对象时必须返回新引用,不能直接修改原数据。
  • 组件使用外部Signal时,只要在JSX或响应式API(如createMemo、createEffect)中调用getter函数,就会自动建立依赖跟踪,触发DOM更新。
  • 事件处理函数需遵循SolidJS的驼峰式命名规范。

内容的提问来源于stack exchange,提问作者Ryan Prentiss

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:48:25