Basic Reactivity

createMemo

编辑此页面

Memo 让你能够在许多响应式计算中高效地使用派生值。 createMemo 创建一个只读的响应式值,该值等于给定函数的返回值,并确保该函数仅在其依赖项发生变化时才会执行。

import { createMemo } from "solid-js"
function createMemo<T>(
fn: (v: T) => T,
value?: T,
options?: { equals?: false | ((prev: T, next: T) => boolean) }
): () => T

以下是 createMemo 的使用示例:

const value = createMemo(() => computeExpensiveValue(a(), b()))
// 读取值
value()

在 Solid 中,你通常不需要将函数包装在 memo 中;你也可以直接定义并调用一个普通函数来获得类似的响应式行为。 主要区别在于当你在多个响应式环境中调用该函数时。 在这种情况下,当函数的依赖项更新时,除非将其包装在 createMemo 中,否则该函数会被多次调用。 例如:

const user = createMemo(() => searchForUser(username()))
// 与此对比: const user = () => searchForUser(username());
return (
<ul>
<li>Your name is {user()?.name}</li>
<li>
Your email is <code>{user()?.email}</code>
</li>
</ul>
)

当 username 信号更新时,searchForUser 只会被调用一次。 如果返回的 user 确实发生了变化,user memo 会更新,然后两个列表项会自动更新。

如果我们将 user 定义为普通函数 () => searchForUser(username()),那么在更新每个列表项时,searchForUser 都会被调用一次,总共调用两次。

另一个关键区别是,当 memo 的依赖项发生变化但结果值没有变化时,memo 可以防止依赖它的组件更新。 与 createSignal 类似,createMemo 创建的派生信号仅在 memo 函数返回的值与之前的值(根据 JavaScript 的 === 运算符)实际发生变化时才会更新(并触发依赖项重新运行)。 另外,你可以传递一个 options 对象,将 equals 设置为 false,这样当依赖项变化时总是会更新 memo,或者你可以传递自己的 equals 函数来测试相等性。

memo 函数调用时会传入一个参数,该参数等于 memo 函数上一次执行的返回值,或者在第一次调用时,等于传给 createMemo 的可选第二个参数。 这对于减少计算非常有用,例如:

// 跟踪 input() 更新时所有值的总和
const sum = createMemo((prev) => input() + prev, 0)

memo 函数不应通过调用 setter 来改变其他信号(它应该是"纯"的)。 这使得 Solid 能够根据它们的依赖关系图优化 memo 更新的执行顺序,以便所有 memo 在响应依赖项更改时最多更新一次。


选项和参数

名称类型描述
fn(v: T) => T要记忆的函数。
valueTmemo 的初始值。
options{ equals?: false | ((prev: T, next: T) => boolean) }一个可选对象,包含用于测试相等性的 equals 函数。
报告此页面问题