当前位置:首页 > 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:

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('');

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

监听对象属性的变化

如果需要监听对象的特定属性,可以使用深度比较或特定属性监听:

react如何实现watch

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 功能的不同途径,开发者可以根据具体需求选择最适合的方案。

分享给朋友:

相关文章

如何学react

如何学react

学习 React 的基础知识 React 是一个用于构建用户界面的 JavaScript 库。学习 React 的第一步是掌握其核心概念,包括组件、状态(State)、属性(Props)和生命周期方法…

vue如何实现到期提醒

vue如何实现到期提醒

实现思路 在Vue中实现到期提醒功能,可以通过计算日期差、定时检查和通知用户三个核心步骤完成。需要结合Vue的响应式特性和JavaScript的日期处理能力。 计算日期差 使用JavaScr…

如何下载react

如何下载react

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

react如何折叠

react如何折叠

在 React 中实现折叠功能 使用 useState 管理折叠状态 通过 useState 定义一个状态变量来控制折叠面板的显示与隐藏。例如: const [isCollapsed, setIsC…

react如何重新加载

react如何重新加载

重新加载当前页面 在React中重新加载当前页面可以通过window.location.reload()方法实现。该方法会强制浏览器重新加载当前URL,类似于按下F5刷新页面。 const relo…

react如何减少伤害

react如何减少伤害

减少 React 应用性能伤害的方法 使用 React.memo 或 PureComponent 对于函数组件,使用 React.memo 进行浅比较,避免不必要的重新渲染。类组件可以使用 PureC…