如何在Solid-js中仅监听对象指定属性?实现类似Vue3 watch的效果
在Solid.js中仅监听对象特定属性的变化
你遇到的问题是因为createSignal是针对整个对象的引用进行依赖追踪的:每次修改age并返回新对象时,obj()的引用发生了变化,而你的on依赖函数里访问了obj().name,这会让Solid认为整个obj信号是依赖项,所以任何属性修改都会触发createEffect。
下面是几种解决方法,实现类似Vue3中watch仅监听特定属性的效果:
方法1:使用createStore(推荐)
createStore是Solid专门用于处理复杂状态的API,它支持细粒度的属性追踪,只会在你访问的具体属性变化时触发依赖更新:
import { createStore, createEffect, on } from 'solid-js'; const App: Component = () => { const [obj, setObj] = createStore({ name: "John", age: 30, }); createEffect( on( () => obj.name, (value) => { console.log("name", value); } ) ); return () => ( <button onClick={() => setObj("age", prev => prev + 1)}>+</button> ); };
这里修改age时,只会更新age相关的依赖,监听obj.name的createEffect不会被触发。
方法2:拆分独立的Signal
如果对象的属性不需要作为整体管理,可以把需要单独监听的属性拆成独立的Signal:
import { createSignal, createEffect, on } from 'solid-js'; const App: Component = () => { const [name, setName] = createSignal("John"); const [age, setAge] = createSignal(30); createEffect( on( name, (value) => { console.log("name", value); } ) ); return () => ( <button onClick={() => setAge(prev => prev + 1)}>+</button> ); };
这种方式依赖关系最清晰,修改age完全不会影响监听name的逻辑。
方法3:用createMemo缓存属性值
如果必须使用createSignal存储对象,可以用createMemo缓存name的值,只有当name实际变化时才会更新:
import { createSignal, createEffect, on, createMemo } from 'solid-js'; const App: Component = () => { const [obj, setObj] = createSignal({ name: "John", age: 30, }); const name = createMemo(() => obj().name); createEffect( on( name, (value) => { console.log("name", value); } ) ); return () => ( <button onClick={() => setObj(prev => ({ ...prev, age: prev.age + 1 }))}>+</button> ); };
createMemo会对比前后的name值,只有当值真正改变时才会触发后续的createEffect,修改age时name值不变,所以effect不会执行。
内容的提问来源于stack exchange,提问作者clencat
相关产品推荐
相关产品推荐

