Solid.js 最新官方文档翻译(2)—— 响应式介绍

前言

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

目前 Solid.js 发布了最新的官方文档,但却缺少对应的中文文档。为了帮助大家学习 Solid.js,故有此系列。

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

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

欢迎围观朋友圈、加入低调务实优秀中国好青年前端社群,感受不一样的前端社群。

响应式介绍

注意:虽然本指南对于理解响应式系统很有帮助,但它会用到一些 Solid 中才有的术语。

响应式(Reactivity)增强了 Solid 应用程序的交互性。这种编程范式是指系统自动响应数据或状态变化的能力。对于 Solid,响应式是其设计基础,确保应用程序与底层数据保持最新。

响应式的重要性

  1. 响应式使用户界面 (UI) 和状态保持同步,从而减少手动更新的需要。
  2. 实时更新创造了更具响应性和交互性的用户体验。
javascript 复制代码
function Counter() {
    const [count, setCount] = createSignal(0);
    const increment = () => setCount((prev) => prev + 1);

    return (
        <div>
            <span>Count: {count()}</span>{" "}
            {/* 当按钮点击的时候,只有 `count()` 会被更新 */}
            <button type="button" onClick={increment}>
                Increment
            </button>
        </div>
    );
}

在这段代码中,Counter 函数设置了一个按钮,当点击该按钮时,调用 increment 函数将 count加 1。更新时,只会更新展示的数字,而不会重新渲染整个组件。

响应式原理

信号(Signals)

信号是响应式系统的核心元素,在数据管理和系统响应中发挥着重要作用。信号负责存储和管理数据,以及触发整个系统的更新。这背后是通过使用 getter 和 setter 来完成的。

scss 复制代码
const [count, setCount] = createSignal(0);
//     ^ getter  ^ setter
  • Getter:负责访问信号当前值的函数。您可以调用 getter 来访问存储在信号中的数据
  • Setter:负责修改信号值的函数。调用 setter 更新信号的值,同时会触发应用程序的响应式更新。
perl 复制代码
console.log(count()); // `count()` 是一个 getter,返回 `count` 的当前值即 `0`.

setCount(1); //  `setCount` 是一个 setter, 更新 `count` 的值.

console.log(count()); // 更新后的 `count` 值是 `1`.

订阅者(Subscribers)

订阅者是响应式系统的另一个核心元素。他们负责跟踪信号的变化并相应地更新系统。它们是自动响应程序,保持系统与最新的数据变化同步。

订阅者的工作原理基于两个主要动作:

  • 观察(Observation) : 本质上,订阅者观察信号,这使得订阅者随时准备好捕捉它们正在追踪的信号的任何变化。
  • 响应(Response) : 当信号发生变化时,订阅者会收到通知。这会触发订阅者对信号的变化做出响应。这可能包括更新 UI 或调用外部函数等任务。
scss 复制代码
function Counter() {
    const [count, setCount] = createSignal(0);
    const increment = () => setCount((prev) => prev + 1);

    createEffect(() => {
        console.log(count());
    });
    // 每次 `count` 值改变,`createEffect` 都会触发 console log.
}

状态管理

状态管理是指管理应用程序状态的过程。这涉及存储和更新数据,以及响应数据的变化。

在 Solid 中,状态管理通过信号和订阅者实现。信号用于存储和更新数据,而订阅者用于响应数据变化。

追踪变化

追踪变化涉及监控数据的任何更新并相应地做出响应。这是通过使用订阅者来完成的。

当信号在追踪作用域内未被访问时,对信号的更新将不会触发更新。这是因为如果信号没有被追踪,它无法通知任何订阅者发生了变化。

scss 复制代码
const [count, setCount] = createSignal(0);

console.log("Count:", count());

setCount(1);

// 输出: Count: 0

// `count` 没有被追踪, 所以当 `count` 改变的时候,console log 不会更新.

由于初始化是一次性事件,虽然访问了信号,但在追踪作用域之外,所以不会追踪该信号。要想追踪信号,需要在订阅者的作用域内访问该信号。响应式原语(Reactive primitives),例如 effects,可用于创建订阅者。

scss 复制代码
const [count, setCount] = createSignal(0);

createEffect(() => {
    console.log("Count:", count());
});

setCount(1);

// 输出: Count: 0
//       Count: 1

更新 UI

Solid 应用程序的 UI 使用 JSX 构建。JSX 在幕后创建了一个追踪作用域,这使得可以在组件的返回语句中追踪信号。

javascript 复制代码
function Counter() {
    const [count, setCount] = createSignal(0);
    const increment = () => setCount((prev) => prev + 1);

    return (
        <div>
            <span>Count: {count()}</span>{" "}
            {/* ✅ 当 `count()` 改变时会更新. */}
            <button type="button" onClick={increment}>
                Increment
            </button>
        </div>
    );
}

组件与其他函数非常相似,只会运行一次。这意味着如果在 return 语句之外访问信号,它将在初始化时运行,但对该信号的任何更新都不会触发更新。

javascript 复制代码
function Counter() {
    const [count, setCount] = createSignal(0);
    const increment = () => setCount((prev) => prev + 1);

    console.log("Count:", count()); // ❌ 不会被追踪 - 只会在初始化的时候运行一次.

    createEffect(() => {
        console.log(count()); // ✅ 只要 `count()` 改变,就会更新.
    });

    return (
        <div>
            <span>Count: {count()}</span>{/* ✅ 只要 `count()` 改变,就会更新. */}
            <button type="button" onClick={increment}>
                Increment
            </button>
        </div>
    );
}

了解更多在 Solid 中管理状态的内容,请访问状态管理指南

同步 vs. 异步

响应式系统旨在对数据的变化做出响应。这些响应可以是即时的,也可以是延迟的,具体取决于系统的性质。通常,这两者之间的选择取决于应用程序的要求和所涉及任务的性质。

同步响应

同步响应是 Solid 的默认响应模式,在这种模式下,系统以直接和线性的方式响应变化。当信号发生变化时,对应的订阅者会立即有序更新。

通过同步响应,系统能够以可预测的方式响应变化。这在讲究更新顺序的场景中非常有用。例如,如果一个订阅者依赖于另一个信号,那么就需要确保在其依赖的信号之后更新订阅者。

scss 复制代码
const [count, setCount] = createSignal(0);
const [double, setDouble] = createSignal(0);

createEffect(() => {
    setDouble(count() * 2);
});

在这个例子中,因为同步响应,double 将始终在 count 之后更新。这可确保 double 始终与 count 的最新值保持同步。

异步响应

异步响应是指系统以延迟或非线性的方式响应变化。当信号发生变化时,相应的订阅者不会立即更新。相反,系统会等待特定事件或任务完成后再更新订阅者。

这在订阅者依赖多个信号的场景中非常重要。在这些场景下,在另一个信号之前更新一个信号可能会导致数据不一致。所以如果订阅者依赖于两个信号,系统需要在更新订阅者之前等待两个信号都更新。

注意:当存在异步响应时,确保系统能够在更新时处理延迟非常重要。 batch 可用于延迟更新,以便订阅者在每个信号都更新后运行。

关键概念

  • 信号是响应式系统的核心元素。它们负责存储和管理数据
  • 信号基于 getter 和 setter,所以信号既可读又可写。
  • 订阅者是自动响应,可以追踪信号的变化并相应地更新系统。
  • 信号和订阅者一起确保了系统能够与最新的数据变化保持一致。
  • 响应式系统建立在数据驱动响应式的原则之上。这意味着系统的响应式是由其构建的数据驱动的。
  • 响应式系统可以是同步的,也可以是异步的。

如果您想更深入地了解,请访问有关细粒度响应式指南

相关推荐
Domain-zhuo几秒前
Webpack中loader的作用/ loader是什么?
前端·javascript·vue.js·webpack·node.js·vue
一朵好运莲5 分钟前
React:闭包陷阱产生和解决
前端·javascript·react.js
开花大馒头7 分钟前
在项目中import 语句通常遵循的顺序规范
前端·javascript·react.js
GISer_Jing9 分钟前
React状态管理常见面试题目(一)
前端·react.js·面试
男孩1210 分钟前
初见react
前端·react.js·前端框架
此恨无穷13 分钟前
react源码探索之预先知识了解
前端·react.js·前端框架
Summer_Uncle14 分钟前
【Vue3学习】setup语法糖中的ref,reactive,toRef,toRefs
前端·vue.js·typescript
清风夜半42 分钟前
把鸽鸽放到地图上唱跳rap篮球需要几步?
前端·游戏·three.js
凉生阿新1 小时前
【Vue.js 3.0】provide 、inject 函数详解
前端·vue.js
虾球xz1 小时前
游戏引擎学习第49天
前端·学习·游戏引擎