Memo
缓存渲染组件,仅在监听的依赖项变化时重新渲染。
API 参考
语法
<Memo watch={watchSource} deep={boolean?}>
  {(value) => ReactNode}
</Memo>属性
watch: 要监听的数据源(store、函数或任何值)deep(可选): 启用深度相等检查以处理嵌套对象children: 接收监听值的渲染函数
示例
昂贵组件优化
import { createStore, Memo } from "zenbox";
const dataStore = createStore({
  items: Array.from({ length: 1000 }, (_, i) => ({
    id: i,
    value: Math.random(),
    name: `Item ${i}`,
  })),
  threshold: 0.5,
});
function ExpensiveVisualization() {
  return (
    <div>
      <h2>数据可视化</h2>
      <Memo
        watch={() => ({
          items: dataStore.value.items,
          threshold: dataStore.value.threshold,
        })}
      >
        {({ items, threshold }) => {
          console.log("渲染昂贵可视化..."); // 仅在依赖项变化时输出
          // 昂贵计算
          const processedItems = items
            .filter((item) => item.value > threshold)
            .map((item) => ({
              ...item,
              processed: Math.pow(item.value, 2) * Math.sin(item.id),
            }))
            .sort((a, b) => b.processed - a.processed);
          return (
            <div className="expensive-chart">
              <h3>处理后的项目 ({processedItems.length})</h3>
              {processedItems.slice(0, 20).map((item) => (
                <div key={item.id} className="chart-item">
                  {item.name}: {item.processed.toFixed(4)}
                </div>
              ))}
            </div>
          );
        }}
      </Memo>
    </div>
  );
}多 Store 缓存渲染
const cartStore = createStore({
  items: [
    { id: 1, name: "电脑", price: 999, quantity: 1, category: "电子产品" },
    { id: 2, name: "鼠标", price: 25, quantity: 2, category: "电子产品" },
  ],
});
const settingsStore = createStore({
  currency: "¥",
  taxRate: 0.08,
  discountPercent: 0.1,
});
function CartSummary() {
  return (
    <Memo
      watch={() => ({
        items: cartStore.value.items,
        settings: settingsStore.value,
      })}
    >
      {({ items, settings }) => {
        console.log("渲染复杂购物车摘要..."); // 仅在依赖项变化时输出
        // 复杂计算
        const subtotal = items.reduce(
          (sum, item) => sum + item.price * item.quantity,
          0
        );
        const discount = subtotal * settings.discountPercent;
        const tax = (subtotal - discount) * settings.taxRate;
        const total = subtotal - discount + tax;
        return (
          <div className="cart-summary">
            <div className="cart-items">
              {items.map((item) => (
                <div key={item.id} className="cart-item">
                  <span>{item.name}</span>
                  <span>
                    {item.quantity} × {settings.currency} {item.price}
                  </span>
                </div>
              ))}
            </div>
            <div className="cart-totals">
              <div>
                小计: {settings.currency} {subtotal.toFixed(2)}
              </div>
              <div>
                折扣: -{settings.currency} {discount.toFixed(2)}
              </div>
              <div>
                税费: {settings.currency} {tax.toFixed(2)}
              </div>
              <div>
                <strong>
                  总计: {settings.currency} {total.toFixed(2)}
                </strong>
              </div>
            </div>
          </div>
        );
      }}
    </Memo>
  );
}最佳实践
✅ 用于昂贵计算 - 适合包含大量计算的组件
// Good - 昂贵计算受益于缓存
<Memo watch={() => dataStore.value}>
  {(data) => {
    const expensiveResult = heavyComputation(data);
    return <ComplexChart data={expensiveResult} />;
  }}
</Memo>❌ 不要用于频繁变化的数据
// Bad - 计数器频繁变化,使用缓存帮助不大
<Memo watch={() => counterStore.value.count}>
  {(count) => <div>{count}</div>}
</Memo>✅ 明确依赖项 - 只监听影响渲染输出的数据
// Good - 明确依赖项
<Memo
  watch={() => ({ items: store.value.items, threshold: store.value.threshold })}
>
  {({ items, threshold }) => (
    <ProcessedList items={items} threshold={threshold} />
  )}
</Memo>何时使用 Memo vs 其他选项
| 使用场景 | 推荐方式 | 原因 | 
|---|---|---|
| 昂贵计算 | <Memo> | 缓存避免重复计算 | 
| 简单 store 访问 | usePick 或 useStore | 简单情况下开销更少 | 
| 副作用 | useWatch 或 useWatchEffect | Memo 用于渲染,不适合副作用 | 
| 频繁变化的数据 | 普通组件 | 数据频繁变化时缓存无效 | 
相关文档
<Watch>- 无缓存的响应式渲染组件useComputed- 响应式更新的计算值useStore- 同步 store 最新状态