入门教程 - 细粒度响应式编程

知识库
知识库文档
/tech-stacks/solidjs/tutorial/入门教程 - 细粒度响应式编程.md

文档

Solid.js 入门教程:细粒度响应式编程

一、Solid.js 是什么?

Solid.js 由 Ryan Carniato 创建,外观与 React 很像(JSX、组件、Hooks 风格 API),但底层机制完全不同:

  • 无虚拟 DOM:组件只执行一次,JSX 编译为真实 DOM 操作
  • 细粒度响应式:不是"状态变了 → 重新渲染组件",而是"状态变了 → 直接更新 DOM 中用到该状态的那个文本节点"
  • 性能极致:在 JS 框架 Benchmark 中长期排第一

核心哲学

"组件是组织的概念,不是渲染的概念"

二、Signal:最小响应单元

import { createSignal } from "solid-js";

// 返回 [getter, setter] 对
const [count, setCount] = createSignal(0);

count();        // 读取 → 自动追踪
setCount(1);    // 设置 → 通知所有依赖
setCount(c => c + 1); // 函数式更新

Signal vs React State

React useState Solid createSignal
存储位置 组件实例 闭包(独立于组件)
读取方式 count(值) count()(函数调用)
更新效果 组件重新渲染 仅更新依赖此 signal 的 DOM
可在组件外

三、Effect:副作用自动追踪

import { createEffect } from "solid-js";

createEffect(() => {
  // 自动追踪内部访问的所有 signal
  console.log(`新值:${count()}`);
  localStorage.setItem("count", String(count()));
  // 当且仅当 count() 变化时执行
});

Effect 的自动清理

createEffect(() => {
  const timer = setInterval(() => console.log("tick"), 1000);
  // Solid 自动追踪首次执行后的返回值
  onCleanup(() => clearInterval(timer));
  // 当 effect 重新执行或组件销毁时自动调用
});

四、派生状态:Memo

import { createMemo } from "solid-js";

const [items, setItems] = createSignal([1, 2, 3]);

// 仅在依赖变化时重新计算,否则返回缓存值
const total = createMemo(() => {
  console.log("重新计算 total");
  return items().reduce((sum, n) => sum + n, 0);
});

// 多次 total() 只会计算一次

五、控制流组件

Solid 用组件而非指令做条件/循环(因为组件只在需要时执行):

import { Show, Switch, Match, For, Index } from "solid-js";

<Show when={user()} fallback={<p>请登录</p>}>
  <Dashboard user={user()} />
</Show>

<Switch>
  <Match when={status() === "loading"}><Spinner /></Match>
  <Match when={status() === "error"}><Error message={error()} /></Match>
  <Match when={true}><Content /></Match>
</Switch>

{/* For:按值追踪,适合不可变列表 */}
<For each={todos()}>
  {(todo, index) => <li>{index()}: {todo.text}</li>}
</For>

{/* Index:按索引追踪,适合大量静态元素 */}
<Index each={photos()}>
  {(photo, index) => <img src={photo().url} />}
</Index>

六、生命周期

import { onMount, onCleanup } from "solid-js";

onMount(() => {
  // DOM 已挂载
  fetch("/api/data").then(/* ... */);
});

onCleanup(() => {
  // 组件销毁前
  // 取消订阅、清除定时器等
});

七、资源管理:createResource

import { createResource } from "solid-js";

const [userId, setUserId] = createSignal(1);

const [user, { mutate, refetch }] = createResource(userId, async (id) => {
  const res = await fetch(`/api/users/${id}`);
  return res.json();
});

// user() → undefined(loading)或数据
// user.loading → true/false
// user.error → Error 或 undefined
// mutate(optimisticData) → 乐观更新

八、与 React 的关键区别

React Solid
useState = 组件级状态 createSignal = 独立于组件
useEffect = 依赖数组手动指定 createEffect = 自动追踪
useMemo / useCallback 手动优化 createMemo 自动缓存
组件 re-render = 函数重新执行 组件函数只执行一次
需要 key 做列表 diff For 按值追踪,无需 key

九、思考题

  1. 为什么 createSignal 可以在组件外部使用?这对状态管理意味着什么?
  2. 如果你在 createEffect 中不读取任何 signal,effect 会执行几次?
  3. Solid 的 ForIndex 有何区别?在什么场景该用哪个?

信息

路径
/tech-stacks/solidjs/tutorial/入门教程 - 细粒度响应式编程.md
更新时间
2026/5/31