SolidJs之响应式

338 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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 }));