useStoreValue / useComputed
订阅 store 状态变化和创建计算值
useStoreValue
useStoreValue
是一个 React Hook,可以用它来读取 store 里的值。
它类似于 store.value
,但会在 store 状态变化时触发组件重新渲染。
所以你可以用它来保持组件状态与 store 的同步,非常方便。
// ✅ 组件会在状态变化时自动重新渲染
function Counter1() {
const { count } = useStoreValue(counterStore);
return <div>当前计数: {count}</div>;
}
// ❌ 组件不会在状态变化时重新渲染
function Counter2() {
const count = counterStore.value.count;
return <div>初始计数: {count}</div>;
}
usePick
如果组件只需要 store 中的几个属性,你可以使用 pick
来选择特定属性。
这样组件只会在选定属性变化时重新渲染。
const { name, followers } = useStoreValue(userStore, {
pick: ["name", "followers"],
});
或者使用 usePick
选择特定属性,这是 useStoreValue(store, { pick })
的简写。
const { name, followers } = usePick(userStore, "name", "followers");
useComputed
useComputed
类似于 useStoreValue
,但它会在 store 状态变化时重新计算值。
并且只有当计算值发生变化时,它才会触发组件重新渲染。
类似于 Vue 中的 computed
。
const counterStore = createStore({ count: 0 });
function Counter3() {
const isEven = useComputed(() => counterStore.value.count % 2 === 0);
return <div>是偶数: {isEven ? "是" : "否"}</div>;
}
counterStore.setState({ count: 1 }); // ✅ 组件重新渲染(从偶数到奇数)
counterStore.setState({ count: 3 }); // ❌ 未重新渲染(isEven 仍然是 false)
你也可以使用 useComputed
从多个 store 计算值,非常方便:
const store1 = createStore({ count: 1 });
const store2 = createStore({ isEven: true });
const value = useComputed(() => {
return store1.value.count + (store2.value.isEven ? 1 : 0);
});