前言
Solid.js,一个比 React 更 react 的框架。每一个使用 React 的同学,你可以不使用,但不应该不了解。
目前 Solid.js 发布了最新的官方文档,但却缺少对应的中文文档。为了帮助大家学习 Solid.js,为爱发电翻译文档。
我同时搭建了 Solid.js 最新的中文文档站点:solid.yayujs.com ,欢迎勘误。
虽说是翻译,但个人并不喜欢严格遵守原文,为了保证中文阅读流畅,会删减部分语句,对难懂的部分也会另做补充解释,希望能给大家带来一个好的中文学习体验。
欢迎围观我的“朋友圈”、加入“低调务实优秀中国好青年”前端社群,分享技术,带你成长。
Effects
Effects 是当它们所依赖的信号发生变化时触发的函数。它们在管理副作用方面发挥着至关重要的作用,副作用是指在应用程序范围之外发生的操作,例如 DOM 操作、数据获取和订阅。
使用 effect
使用 createEffect
函数创建 effect。该函数采用一个回调函数作为参数,该回调在 effect 被触发时运行。
import { createEffect } from "solid-js";
const [count, setCount] = createSignal(0);
createEffect(() => {
console.log(count());
});
在这个例子中,就创建了一个 effect,将 count
的当前值打印到控制台。当 count
的值发生变化时,会触发该 effect,使其再次运行并打印 count
的新值。
管理依赖关系
Effects 可以设置任意数量的依赖项。依赖项允许 effect 追踪改变并做出响应。这些可以包括信号、变量、props、上下文或其他响应值。当其中任何一个发生变化时,effect 都会接收通知,并将再次运行以更新状态。
初始化后,effect 将运行一次,无论它是否有任何依赖项。这对于设置 effect 和初始化变量或订阅信号非常有用。运行后,仅当其任何依赖项发生更改时才会再次触发 effect。
createEffect(() => {
console.log("hello"); // 只会运行一次
});
createEffect(() => {
console.log(count()); // 每次 count 改变都会运行
});
Solid 会自动追踪 effect 的依赖项,因此无需手动指定它们。这改善了追踪并最大限度地减少了忽略或错误识别依赖项的可能。
订阅信号
当 effect 被设置为观察一个信号时,它会创建对该信号的订阅。此订阅允许 effect 追踪信号值的变化,从而观察可能发生的任何变化并相应地执行其回调。
import { createSignal, createEffect } from "solid-js";
const [count, setCount] = createSignal(0);
createEffect(() => {
console.log(count()); // 无论何时 count 改变都会打印当前值
});
管理多个信号
Effect 具有观察多个信号的能力。单个 Effect 可以订阅多个信号,同样,多个 Effect 可以跟踪单个信号。当您需要根据多个信号更新 UI 时,这非常有用。
当在单个 Effect 中观察到多个信号时,只要任何信号发生变化,它将执行回调。即使只有一个信号发生变化(不一定是所有信号发生变化),效果也会运行。这意味着该 Effect 将以其正在观察的所有信号的最新值运行。
import { createSignal, createEffect } from "solid-js";
const [count, setCount] = createSignal(0);
const [message, setMessage] = createSignal("Hello");
createEffect(() => {
console.log(count(), message());
});
setCount(1); // 输出: 1, "Hello"
setMessage("World"); // 输出: 1, "World"
信息:
当信号更新时,它会按顺序通知所有订阅者,但顺序可能会有所不同。虽然 effect 保证在信号更新时运行,但执行可能不是即时的。这意味着 effect 的执行顺序不受保证且不应依赖。
嵌套 effects
使用 effects 时,可以将它们相互嵌套。这允许每个 effect 独立跟踪其自身的依赖关系,而不影响其嵌套的效果。
createEffect(() => {
console.log("Outer effect starts");
createEffect(() => console.log("Inner effect"));
console.log("Outer effect ends");
});
需要注意执行顺序很重要。内部 effect 不会影响外部 effect。在内部 effect 中访问的信号不会注册为外部effect 的依赖项。当位于内部 effect 内的信号发生变化时,只会触发内部 effect 重新运行,而不会触发外部 effect 重新运行。
import { createSignal, createEffect } from "solid-js";
const [count, setCount] = createSignal(0);
createEffect(() => {
console.log("Outer effect starts");
createEffect(() => console.log(count())); // when count changes, only this effect will run
console.log("Outer effect ends");
});
这迫使每个 effect 彼此独立,这将有助于避免意外行为。此外,它还允许您创建仅在满足特定条件时触发的 effect。
生命周期函数
effect 具有可以使用某些函数进行管理的生命周期。这些函数允许您控制 effect 的初始化和处理,以构建您需要的行为类型。这可以包括仅运行一次副作用,或者在不再需要时清理任务。
onMount
在您只想运行一次副作用的情况下,可以使用 onMount 函数。此生命周期函数类似于 effect,但它不跟踪任何依赖项。相反,一旦组件初始化,onMount
回调将被执行并且不会再次运行。
import { onMount } from "solid-js";
function Component() {
const [data, setData] = createSignal(null);
createEffect(() => {
data(); // will run 每次 data 改变都会运行
});
onMount(async () => {
// 只会在组件挂载时运行一次
const fetchedData = await fetch("https://example.com/data");
setData(fetchedData);
});
return <div>...</div>;
}
onMount
保证回调只会运行一次。如果在这种情况下使用 effect,则不能保证它只会运行一次,这可能会导致意外的行为。这使得 onMount 对于 API 调用和其他副作用非常有用,每个组件实例只需运行一次。
onCleanup
onMount
对于运行一次副作用很有用,而 onCleanup
对于不再需要任务时清理任务很有帮助。 onCleanup
将在组件卸载时运行,删除 effect 具有的订阅。
import { onCleanup } from "solid-js";
function App() {
const [count, setCount] = createSignal(0);
const timer = setInterval(() => {
setCount((prev) => prev + 1);
}, 1000);
onCleanup(() => {
clearInterval(timer);
});
return <div>Count: {count()}</div>;
}
在这个例子中,onCleanup
函数用于清除 effect 中设置的定时器。为了避免定时器无限期地运行,onCleanup
函数用于在组件卸载后清除定时器。
onCleanup
可用于避免内存泄漏。当组件被卸载但对其的引用仍然存在并且因此可能仍然在后台运行时,就会发生这些情况。使用 onCleanup
删除对该组件的任何订阅或引用可以帮助避免此问题。
Solid.js 中文文档
本篇已收录在掘金专栏 《Solid.js 中文文档》,该系列一共 25 篇。下一篇:Solid.js 最新官方文档翻译(12)—— 派生信号与 Memos
此外我还写过 JavaScript 系列、TypeScript 系列、React 系列、Next.js 系列、VuePress 博客搭建系列等 14 个系列文章, 全系列文章目录:github.com/mqyqingfeng…
通过文字建立交流本身就是一种缘分,欢迎围观我的“朋友圈”、加入“低调务实优秀中国好青年”前端社群,分享技术,带你成长。