react 实现 watch
在 React 中实现类似 Vue 的 watch 功能,可以通过以下几种方式监听状态变化并执行副作用:
使用 useEffect 钩子
useEffect 是 React 提供的标准方式,用于监听依赖项的变化并执行副作用。
import { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('count changed:', count);
// 可以在这里执行副作用逻辑
}, [count]); // 依赖数组,仅当 count 变化时触发
return (
<button onClick={() => setCount(count + 1)}>
Increment: {count}
</button>
);
}
自定义 useWatch Hook
封装一个自定义 Hook 来模拟 Vue 的 watch 行为,提供更灵活的监听逻辑。
import { useEffect, useRef } from 'react';
function useWatch(value, callback, options = { immediate: false }) {
const isFirstRun = useRef(true);
useEffect(() => {
if (isFirstRun.current && !options.immediate) {
isFirstRun.current = false;
return;
}
callback(value);
}, [value]);
}
// 使用示例
function Demo() {
const [data, setData] = useState(null);
useWatch(data, (newValue) => {
console.log('data changed:', newValue);
}, { immediate: true });
return <button onClick={() => setData(Date.now())}>Update Data</button>;
}
使用第三方库
一些库(如 ahooks)提供了现成的 useWatch 或类似功能:
import { useWatch } from 'ahooks';
function Component() {
const [state, setState] = useState({});
useWatch(state, (prev, next) => {
console.log('prev:', prev, 'next:', next);
});
return <button onClick={() => setState({ ...state, time: Date.now() })}>Update</button>;
}
对比依赖数组的旧值
在 useEffect 中通过引用对比或深比较实现类似 watch 的旧值访问:
useEffect(() => {
const subscription = someObservable.subscribe();
return () => subscription.unsubscribe(); // 清理函数
}, [someObservable]);
注意事项
- 对于对象或数组等引用类型,需注意浅比较问题,可能需要配合
useMemo或深比较工具。 - 频繁触发的监听可能导致性能问题,可使用防抖(debounce)或节流(throttle)优化。
- Class 组件中可通过
componentDidUpdate实现类似功能。







