useComputed

创建响应式计算值,在依赖项变化时自动更新

API 参考

语法

const computedValue = useComputed(compute, options?)

参数

  • compute: 返回计算值的函数
  • options (可选):
    • deep: 启用深度相等检查以处理嵌套对象/数组(默认:false)

示例

简单计算值

响应式转换 store 数据,自动检测依赖项。

import { createStore, useComputed } from "zenbox";

const userStore = createStore({
  firstName: "张",
  lastName: "三",
  age: 30,
});

function UserProfile() {
  // 在 userStore 的任意属性发生变化时,自动重新计算,仅在 fullName 变化时才会触发重新渲染
  const fullName = useComputed(
    () => `${userStore.value.firstName}${userStore.value.lastName}`
  );

  const ageGroup = useComputed(() => {
    const age = userStore.value.age;
    if (age < 18) return "未成年";
    if (age < 65) return "成年";
    return "老年";
  });

  return (
    <div>
      <h1>{fullName}</h1>
      <p>年龄段: {ageGroup}</p>
    </div>
  );
}

跨 Store 组合

轻松组合多个 store 的数据 - 依赖项自动跟踪。

const cartStore = createStore({
  items: [
    { id: 1, price: 999, quantity: 1 },
    { id: 2, price: 25, quantity: 2 },
  ],
});

const settingsStore = createStore({
  taxRate: 0.08,
  discountPercent: 0.1,
});

function CartSummary() {
  const subtotal = useComputed(() =>
    cartStore.value.items.reduce(
      (sum, item) => sum + item.price * item.quantity,
      0
    )
  );

  const total = useComputed(() => {
    const discount = subtotal * settingsStore.value.discountPercent;
    const tax = (subtotal - discount) * settingsStore.value.taxRate;
    return subtotal - discount + tax;
  });

  return (
    <div>
      <p>小计: ¥{subtotal.toFixed(2)}</p>
      <p>总计: ¥{total.toFixed(2)}</p>
    </div>
  );
}

最佳实践

保持计算纯净 - 无副作用,仅进行数据转换

// ❌ Bad:有副作用
const bad = useComputed(() => {
  localStorage.setItem("count", store.value.count); // 副作用!
  return store.value.count;
});

// ✅ Good:仅进行数据转换
const doubled = useComputed(() => store.value.count * 2);

只依赖需要的属性

// ❌ Bad:依赖整个用户对象
const { name } = useComputed(() => userStore.value);

// ✅ Good:仅依赖名称属性
const userName = useComputed(() => userStore.value.name.toUpperCase());

Hook 比较

Hook用途触发重新渲染使用场景
useComputed派生响应式值✅ 是数据转换、计算属性
useStoreValue直接订阅状态变化✅ 是原始 store 访问
useWatch变化时的副作用❌ 否日志、分析、外部 API

相关 Hook