持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情
响应式批量更新
Solid的响应式是同步的,说明在改变signal的之后立马就可以拿到最新的值。同时dom也会进行更新,但是多个signal的更新会导致频繁的dom更新,浪费性能,但是solid的粒度渲染只在更新在响应式系统中的传播。渲染两次无关的更改实际上并不意味着浪费性能。
如果想把多次更新合并为一次。solid也有办法,它提供了一个batch工具函数。会将多个更改推入对列,然后在通知观察者之前同时使用它们。在批处理中更新的信号值直到批处理完成才会提交。
如:
import { render } from "solid-js/web";
import { createSignal, batch } from "solid-js";
const App = () => {
const [firstName, setFirstName] = createSignal("John");
const [lastName, setLastName] = createSignal("Smith");
const fullName = () => {
console.log("Running FullName");
return `${firstName()} ${lastName()}`
}
const updateNames = () => {
console.log("Button Clicked");
batch(() => {
setFirstName(firstName() + "n");
setLastName(lastName() + "!");
})
}
return <button onClick={updateNames}>My name is {fullName()}</button>
};
render(App, document.getElementById("app"));
在这里例子中,我们在按钮点击时分配了两个名字,触发了渲染更新两次。单击该按钮后,可以在控制台中看到日志。因此,让我们将set调用打包成一个批次。
Untrack
有时候不需要signal被跟踪。可以使用untrack工具函数来避免包装计算跟踪任何读取行为。 如:
import { render } from "solid-js/web";
import { createSignal, createEffect, untrack } from "solid-js";
const App = () => {
const [a, setA] = createSignal(1);
const [b, setB] = createSignal(1);
createEffect(() => {
console.log(a(), untrack(b));
});
return <>
<button onClick={() => setA(a() + 1)}>Increment A</button>
<button onClick={() => setB(b() + 1)}>Increment B</button>
</>
};
render(App, document.getElementById("app"));
我们不想在b更改时输出日志。我们可以通过将Effect更改以下内容来取消跟踪b signal。
on
为了方便起见,solid提供一个on工具函数,可以为我们的计算设置显示依赖。这主要是用来更明确地简洁声明跟踪哪些信号。如果只是在第一次更改而不是立即执行使用defer选项启用此向功能。
createEffect(on(a, (a) => { console.log(a, b()); }, { defer: true }));