Solid.js 最新官方文档翻译(12)—— 派生信号与 Memos

前言

Solid.js,一个比 React 更 react 的框架。每一个使用 React 的同学,你可以不使用,但不应该不了解

目前 Solid.js 发布了最新的官方文档,但却缺少对应的中文文档。为了帮助大家学习 Solid.js,为爱发电翻译文档。

我同时搭建了 Solid.js 最新的中文文档站点:solid.yayujs.com ,欢迎勘误。

虽说是翻译,但个人并不喜欢严格遵守原文,为了保证中文阅读流畅,会删减部分语句,对难懂的部分也会另做补充解释,希望能给大家带来一个好的中文学习体验。

欢迎围观朋友圈、加入低调务实优秀中国好青年前端社群,一个人走得快,一群人走得远。

派生信号

派生信号是依赖一个或多个信号来产生值的函数。

这些函数不会立即执行,而是仅在它们所依赖的值发生改变时才被调用。当底层信号改变时,该函数将被再次调用以产生新值。

javascript 复制代码
const double = () => count() * 2;

在上面的示例中,double 函数依赖于 count 信号来生成值。当 count 信号改变时,double 函数将被再次调用以产生新值。

同样,您可以创建依赖于 store 的派生信号,因为 store 幕后也是使用信号。要了解有关 store 如何运作,您可以访问store 章节

javascript 复制代码
const fullName = () => store.firstName + ' ' + store.lastName;

这些依赖函数从它们访问的信号中获得响应式,确保底层数据的更改在整个应用程序中传播。需要注意的是,这些函数本身并不存储值;相反, 它们可以更新依赖于它们的任何 effect 或组件。如果包含在组件主体中,这些派生信号将在必要时触发更新。

虽然您可以通过这种方式创建派生值,但 Solid 创建了 createMemo。要更深入地了解 memos 如何工作,请查看 memos 章节

Memos

Memos 是一种响应式值,用于记忆化派生装填或昂贵计算。它们与派生信号类似于,因为它们都是响应式值,当它们的依赖关系发生变化时,会自动重新评估。然而,与派生信号不同,memos 经过优化,只对其依赖项的每次更改执行一次。

Memos 提供一个只读响应式值(类似于信号),并跟踪其依赖项的变化(类似于效果)。这使得它们对于昂贵计算或频繁访问的计算结果非常有用。通过这样做,memos 会保留计算记过直到其依赖项发生变化,从而最大限度的减少应用程序中不必要的工作。

使用 memos

使用 createMemo 函数创建一个 memo。在此函数中,您可以定义你希望记忆化的派生值或者计算。调用时,createMemo将返回一个 getter 函数,该函数用于读取 memo 的当前值:

jsx 复制代码
import { createMemo, createSignal } from "solid-js"

const [count, setCount] = createSignal(0)

const isEven = createMemo(() => count() % 2 === 0)

console.log(isEven()) // true

setCount(3)
console.log(isEven()) // false

虽然 memo 看起来与 effect 相似,但它们的不同之处在于它们返回一个值。该值是您希望记住的计算结果或派生状态。

使用 memos 的优势

虽然您可以使用派生信号来获得类似的结果,但 memos 具有明显的优势:

  • Memos 经过优化,只对其依赖项的每次更改执行一次
  • 当处理昂贵的计算时,可以使用 memos 缓存结果,这样就不会不必要地重新计算它们。
  • memos 仅在其依赖项发生变化时才会重新计算,并且如果其依赖项发生变化但其值保持不变,则不会触发后续更新(由 === 或严格相等确定)。
  • memos 函数中的任何信号或 memo 都会被追踪。这意味着当这些依赖项发生变化时,memos 将自动重新评估。

Memo vs. effect

在管理响应式计算和副作用时,Memo 和 effect 都很重要。然而,它们有不同的目的,并且各自有自己独特的行为。

Memos Effects
返回值 是 - 返回计算结果或派生状态的 getter。 不返回值,但执行代码块以响应更改。
缓存结果
行为 函数参数应该是纯的,没有响应式副作用。 函数参数可能会导致 UI 更新或数据获取等副作用。
依赖追踪
示例用例 转换数据结构、计算聚合值、派生状态或其他昂贵的计算。 UI 更新、网络请求或外部集成

最佳实践

纯函数

使用 memos 时,建议您将其写为纯函数:

jsx 复制代码
import { createSignal, createMemo } from "solid-js"

const [count, setCount] = createSignal(0)
const isEven = createMemo(() => count() % 2 === 0) // 一个纯函数示例

纯函数是指不会导致任何副作用的函数。这意味着函数的输出应该仅取决于其输入。

当您在 memos 中引入副作用时,它会使反应链变得复杂。这可能会导致意外行为,例如无限循环,从而导致应用程序崩溃。

jsx 复制代码
import { createSignal, createMemo } from "solid-js"

const [count, setCount] = createSignal(0)
const [message, setMessage] = createSignal("")

const badMemo = createMemo(() => {
    if (count() > 10) {
        setMessage("Count is too high!") //  副作用
    }
    return count() % 2 === 0
})

当 memos 具有导致其依赖关系发生变化的副作用时,可能会触发无限循环。这将导致 memos 重新评估,然后再次触发副作用,依此类推,直到应用程序崩溃。

可以通过使用 createEffect 来处理副作用来避免这种情况:

jsx 复制代码
import { createSignal, createMemo, createEffect } from "solid-js"

const [count, setCount] = createSignal(0)
const [message, setMessage] = createSignal("")

const isEven = createMemo(() => count() % 2 === 0)

createEffect(() => {
    if (count() > 10) {
        setMessage("Count is too high!")
    }
})

在这里, createEffect 将处理副作用,而 isEven memo 将保持为纯函数。

在 memos 中保留逻辑

Memos 经过优化,只会对其依赖项的每次改变执行一次。这意味着您可以删除由 Memos 的依赖项触发的不必要的效果。

在处理派生状态时,Memos 是优于 effects 的推荐方法。将逻辑保留在 Memos 中可以防止使用 effects 时可能发生的不必要的重新渲染。同样,effects 更适合处理副作用,例如 DOM 更新,而不是派生状态。这种关注点分离可以帮助保持代码整洁且易于理解。

jsx 复制代码
// effect - 无论何时 `count` 改变都会运行
createEffect(() => {
    if (count() > 10) {
        setMessage("Count is too high!")
    } else {
        setMessage("")
    }
})

// memo - 只有当 `count` 改变到值大于 10 ,才会运行
const message = createMemo(() => {
    if (count() > 10) {
        return "Count is too high!"
    } else {
        return ""
    }
})

系列文章

本篇已收录在掘金专栏 《Solid.js 中文文档》

此外我还写过 React 系列TypeScript 系列Next.js 系列VuePress 博客搭建系列JavaScript 系列等多个系列文章,全系列文章目录:github.com/mqyqingfeng...

通过文字建立交流本身就是一种缘分,欢迎围观朋友圈、加入低调务实优秀中国好青年前端社群,一个人走得快,一群人走得远。

相关推荐
过往记忆2 小时前
告别 Shuffle!深入探索 Spark 的 SPJ 技术
大数据·前端·分布式·ajax·spark
高兴蛋炒饭3 小时前
RouYi-Vue框架,环境搭建以及使用
前端·javascript·vue.js
m0_748240443 小时前
《通义千问AI落地—中》:前端实现
前端·人工智能·状态模式
ᥬ 小月亮3 小时前
Vue中接入萤石等直播视频(更新中ing)
前端·javascript·vue.js
夜斗(dou)4 小时前
node.js文件压缩包解析,反馈解析进度,解析后的文件字节正常
开发语言·javascript·node.js
恩爸编程4 小时前
纯 HTML+CSS+JS 实现一个炫酷的圣诞树动画特效
javascript·css·html·圣诞树·圣诞树特效·圣诞树js实现·纯js实现圣诞树
神雕杨4 小时前
node js 过滤空白行
开发语言·前端·javascript
网络安全-杰克4 小时前
《网络对抗》—— Web基础
前端·网络
m0_748250744 小时前
2020数字中国创新大赛-虎符网络安全赛道丨Web Writeup
前端·安全·web安全
周伯通*5 小时前
策略模式以及优化
java·前端·策略模式