const App: Component = () => {
const [obj, setObj] = createSignal({
name: "John",
age: 30,
})
createEffect(
on(
() => obj().name,
(value) => {
console.log("name", value)
}
)
)
return ()=>(<button onClick={()=> setObj(obj=> ({ ...obj, age: obj.age + 1}))}>+</button>)
}当我更改age时,createEffect也会被触发,我只想监听name,类似于Vue3中的watch。
function setup(){
const obj = reactive({
name: "John",
age: 30,
})
watch(()=> obj.name,(value)=>{ console.log("name", value) })
}有什么好主意吗?
发布于 2022-09-27 18:10:30
信号是提供单向数据流的原子值,这意味着通过设置新值来更新信号。即使传递相同的属性,也将设置一个新对象,因为在JavaScript中通过引用来比较对象,从而触发更新。
也就是说,有多种方法或方法来跟踪存储在信号中的对象的单个属性。
使用商店的
createStore在内部使用代理,并提供跟踪单个属性的方法。您可以使用produce,一种用于本地化突变的加密API,因此只更新某些属性。。
import { render } from "solid-js/web";
import { createSignal, createMemo, createEffect } from "solid-js";
function App() {
const [person, setPerson] = createSignal({ name: "John Doe", age: 20 });
const handleClick = () => setPerson({ name: "Jenny Doe", age: 20 });
const age = createMemo(() => person().age);
createEffect(() => {
console.log("Age is updated", age());
});
return (
<button type="button" onClick={handleClick}>
{JSON.stringify(person())}
</button>
);
}
render(App, document.getElementById("app")!);solid-js
on实用程序import { render } from "solid-js/web";
import { createSignal, createEffect, on } from "solid-js";
import { createStore } from "solid-js/store";
function App() {
const [person, setPerson] = createStore({ name: 'John Doe', age: 30 });
const increment = () => setPerson(p => ({ ...p, age: p.age + 1 }));
createEffect(on(() => person.name, () => {
console.log('Tracking name');
}));
createEffect(on(() => person.age, () => {
console.log('Tracking age');
}));
return (
<button type="button" onClick={increment}>
{person.name} {person.age}
</button>
);
}
render(App, document.getElementById("app")!);此方法也适用于信号:
import { render } from "solid-js/web";
import { createSignal, createEffect, on } from "solid-js";
function App() {
const [person, setPerson] = createSignal({ name: 'John Doe', age: 30 });
const increment = () => setPerson(p => ({ ...p, age: p.age + 1 }));
createEffect(on(() => person.name, () => {
console.log('Tracking name');
}));
createEffect(on(() => person().age, () => {
console.log('Tracking age');
}));
return (
<button type="button" onClick={increment}>
{person().name} {person().age}
</button>
);
}
render(App, document.getElementById("app")!);您可以在createSignal:中使用参数
import { render } from "solid-js/web";
import { createSignal, createEffect, on } from "solid-js";
function App() {
const [person, setPerson] = createSignal(
{ name: "John Doe", age: 20 },
{ equals: (prev, next) => prev.age === next.age }
);
const handleClick = () => setPerson({ name: "Jenny Doe", age: 20 });
createEffect(() => {
console.log("Age is updated", person());
});
return (
<button type="button" onClick={handleClick}>
{JSON.stringify(person())}
</button>
);
}
render(App, document.getElementById("app")!);这些都是开箱即用的解决方案,但由于Solid非常灵活,而且非常宽松,如果您愿意,可以实现您自己的逻辑。
发布于 2022-09-10 03:08:06
SolidJS将不会跟踪信号对象的单个属性。
此外,每当一个值在销毁时发生变化时,您都会覆盖该对象(也就是。{...obj,}
如果希望createEffect跟踪单个属性,请尝试createStore。
下面是用createStore而不是createSignal编写的示例
import {createStore} from 'solid-js/store'; // <- This is very important
const App: Component = () => {
const [obj, setObj] = createStore({
name: "John",
age: 30,
})
createEffect(() => console.log(obj.name));
return (<button onClick={setObject('age', obj.age + 1)}>+</button>)
)
}如果您运行这个示例,您将看到console.log(obj.name)只运行一次,这是因为solid-js在将它们保存在createStore上时会跟踪它们的各个属性。
https://stackoverflow.com/questions/73440069
复制相似问题