react如何实现watch
在 React 中实现类似 Vue 的 watch 功能
React 本身没有内置的 watch 机制,但可以通过多种方式实现类似功能。以下是几种常见方法:
使用 useEffect 监听状态变化
useEffect 是 React 提供的 Hook,可以用来监听特定状态的变化:
import { useState, useEffect } from 'react';
function Component() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('count changed:', count);
// 这里可以执行count变化后的逻辑
}, [count]); // 依赖数组中放入要监听的状态
return (
<button onClick={() => setCount(count + 1)}>
Increment: {count}
</button>
);
}
使用自定义 Hook 封装 watch 功能
可以创建一个自定义 Hook 来模拟 Vue 的 watch:
import { useEffect, useRef } from 'react';
function useWatch(value, callback, config = { immediate: false }) {
const oldValue = useRef();
const isFirst = useRef(true);
useEffect(() => {
if (isFirst.current && !config.immediate) {
isFirst.current = false;
return;
}
callback(value, oldValue.current);
oldValue.current = value;
}, [value]);
}
// 使用示例
function Component() {
const [count, setCount] = useState(0);
useWatch(count, (newVal, oldVal) => {
console.log('count changed from', oldVal, 'to', newVal);
});
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
使用第三方库
一些第三方库提供了更完善的 watch 功能:
- ahooks 的 useWatch
import { useWatch } from 'ahooks';
function Demo() { const [value, setValue] = useState('');
useWatch(value, (newVal, oldVal) => { console.log('value changed', oldVal, '->', newVal); });
return <input value={value} onChange={e => setValue(e.target.value)} />; }
2. react-use 的 usePrevious + useEffect
```javascript
import { usePrevious } from 'react-use';
function Demo() {
const [count, setCount] = useState(0);
const prevCount = usePrevious(count);
useEffect(() => {
if (prevCount !== undefined && prevCount !== count) {
console.log('count changed', prevCount, '->', count);
}
}, [count]);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
监听对象属性的变化
如果需要监听对象的特定属性,可以使用深度比较或特定属性监听:

import { useEffect, useRef } from 'react';
import { isEqual } from 'lodash';
function useDeepCompareEffect(callback, dependencies) {
const currentDepsRef = useRef();
if (!isEqual(currentDepsRef.current, dependencies)) {
currentDepsRef.current = dependencies;
}
useEffect(callback, [currentDepsRef.current]);
}
// 使用示例
function Component() {
const [user, setUser] = useState({ name: 'John', age: 30 });
useDeepCompareEffect(() => {
console.log('user changed:', user);
}, [user]);
return (
<button onClick={() => setUser(u => ({ ...u, age: u.age + 1 }))}>
Increment Age
</button>
);
}
性能优化注意事项
- 避免在 useEffect 中执行昂贵操作
- 合理设置依赖数组,避免不必要的重新渲染
- 对于复杂对象考虑使用 memoization 或浅比较
- 需要清理的副作用应在 useEffect 返回的函数中处理
这些方法提供了在 React 中实现类似 Vue watch 功能的不同途径,开发者可以根据具体需求选择最适合的方案。






