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
相关产品推荐
相关产品推荐

