useWatch / useWatchEffect
订阅 store 状态变化和执行副作用,不会触发组件重新渲染
useWatch
useWatch
是一个 React Hook,允许你订阅 store 的状态变化,并执行副作用。
它类似于 useStoreValue
,但不会在状态变化时触发组件重新渲染,非常适合执行副作用。
例如,你可以用它来记录状态变化:
useWatch(
() => counterStore.value.count,
(current, prev) => {
console.log("count 变化了", current, prev);
}
);
默认情况下,它会在状态变化时触发副作用,而非立即执行。
立即执行
如果你想立即触发副作用,可以使用 immediate: true
选项。
useWatch(
() => counterStore.value.count,
(current, prev) => {
console.log("立即执行副作用", current, prev);
},
{ immediate: true }
);
只运行一次
如果你只想触发一次副作用,可以使用 once: true
选项。
useWatch(
() => counterStore.value.count,
(current, prev) => {
console.log("只运行一次", current, prev);
},
{ once: true }
);
清理函数
你也可以返回一个函数来清理副作用。清理函数会在组件卸载或下一个副作用运行前执行。
useWatch(
() => counterStore.value.count,
(current, prev) => {
if (current > 10) {
const handleClick = () => {
console.log("当前计数", counterStore.value.count);
};
window.addEventListener("click", handleClick);
return () => {
window.removeEventListener("click", handleClick);
};
}
}
);
监听多个 store
你也可以同时监听多个 store。
useWatch(
() => [counterStore.value, userStore.value] as const, // ✅ 使用 `as const` 推断类型
([counter, user]) => {
console.log("counter 和 user 变化了", counter.count, user.name);
}
);
注意:
- 如果你想监听 store 数组,可以使用
[x, y, z] as const
来自动推断 TypeScript 类型。
useWatchEffect
useWatchEffect
类似于 useWatch
,但副作用会在构建组件时立即运行。
它会自动收集依赖并在依赖变化时触发副作用。
useWatchEffect(() => {
if (counterStore.value.count > 10) {
console.log("count 大于 10");
}
});
同时支持清理函数。
useWatchEffect(() => {
if (counterStore.value.count > 10) {
const handleClick = () => {
console.log("当前计数", counterStore.value.count);
};
window.addEventListener("click", handleClick);
return () => {
window.removeEventListener("click", handleClick);
};
}
});