当前位置:首页 > React

react如何实现watch

2026-03-31 09:43:05React

在 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:

react如何实现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 功能:

  1. ahooks 的 useWatch
    
    import { useWatch } from 'ahooks';

function Demo() { const [value, setValue] = useState('');

react如何实现watch

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>
  );
}

性能优化注意事项

  1. 避免在 useEffect 中执行昂贵操作
  2. 合理设置依赖数组,避免不必要的重新渲染
  3. 对于复杂对象考虑使用 memoization 或浅比较
  4. 需要清理的副作用应在 useEffect 返回的函数中处理

这些方法提供了在 React 中实现类似 Vue watch 功能的不同途径,开发者可以根据具体需求选择最适合的方案。

分享给朋友:

相关文章

vue如何实现两栏布局

vue如何实现两栏布局

使用Flexbox实现两栏布局 Flexbox是CSS3中强大的布局方式,可以轻松实现两栏布局。在Vue中可以直接在组件的style标签中使用。 <template> <div…

如何下载react

如何下载react

下载 React 的方法 通过 npm 或 yarn 安装 React 可以通过包管理器 npm 或 yarn 安装。确保已安装 Node.js(包含 npm),然后在项目目录中运行以下命令:…

vue如何实现排序

vue如何实现排序

实现数组排序 在Vue中可以通过计算属性或方法对数组进行排序。使用JavaScript的sort()方法结合Vue的响应式特性实现动态排序。 data() { return { item…

如何恢复react

如何恢复react

恢复 React 项目的方法 检查并修复依赖项 运行 npm install 或 yarn install 重新安装所有依赖项。如果依赖项损坏或缺失,这将恢复项目所需的库和工具。 恢复删除的文件 如…

react如何实现插槽

react如何实现插槽

React 实现插槽的方法 React 本身没有直接提供类似 Vue 的插槽(slot)概念,但可以通过以下几种方式实现类似功能: 使用 props.children React 组件可以通过 pr…

react如何检测窗口

react如何检测窗口

监听窗口大小变化 使用useEffect钩子和resize事件监听窗口尺寸变化。在组件挂载时添加事件监听器,卸载时移除监听器以避免内存泄漏。 import { useState, useEffect…