全书目录

第四十篇:SolidStart 完全指南 —— 精细反应街区宇宙

第五章:Effect 和 Memo —— 巡检员 vs 统计牌

1 分钟 294 字 第 775 / 962 个阅读单元

#1. createEffect:街区巡检员

createEffect 用来处理副作用。

tsx
import { createSignal, createEffect } from "solid-js";

function Demo() {
  const [count, setCount] = createSignal(0);

  createEffect(() => {
    console.log("最新计数:", count());
  });

  return <button onClick={() => setCount(count() + 1)}>{count()}</button>;
}

它会自动追踪里面读到的 signal。 你不需要像 React 那样手写依赖数组。

text
createEffect(() => {
  console.log(count(), user(), mode())
})

等价于:
这个巡检员会盯着 count / user / mode
谁变了,它就重新巡检

#2. createMemo:街区统计牌

如果一个值是从别的响应式值推导出来的,优先用 createMemo

tsx
import { createSignal, createMemo } from "solid-js";

function PriceBoard() {
  const [price, setPrice] = createSignal(100);
  const [count, setCount] = createSignal(3);

  const total = createMemo(() => price() * count());

  return (
    <div>
      <p>单价: {price()}</p>
      <p>数量: {count()}</p>
      <p>总价: {total()}</p>
      <button onClick={() => setCount(c => c + 1)}>+1</button>
    </div>
  );
}

#3. 一个重要规则

派生值用 createMemo,副作用才用 createEffect

不要把本来可以“算出来”的值,先塞进 signal,再在 effect 里同步。

错误思路:

tsx
const [firstName] = createSignal("Mizzen");
const [lastName] = createSignal("AI");
const [fullName, setFullName] = createSignal("");

createEffect(() => {
  setFullName(`${firstName()} ${lastName()}`);
});

更好的写法:

tsx
const fullName = createMemo(() => `${firstName()} ${lastName()}`);

在精细反应街区里:

  • memo 是“自动统计牌”
  • effect 是“拿着对讲机去影响外部世界的人”

别混用。