当前位置: 首页 > article >正文

从watch、watchEffect、useEffect原理到vue、react响应原理

正文

1.核心原理
  • Vue中的watchwatchEffect是基于Vue的响应式系统(Proxy),依赖于refreactive数据的变化。
  • React中的useEffect基于状态驱动的重新渲染机制,通过依赖数组 [dependency],手动声明需要追踪的状态或属性。
2.功能

Vue中的watch:

  • 专门用于监听指定响应式数据或计算属性的变化。
  • 回调函数提供两个参数:新值和旧值。
  • 常用于对特定数据的精准监听,比如异步操作、深度监听对象等。
    watch(data, (newVal, oldVal) => {
      console.log('Data changed:', oldVal, '->', newVal);
    });
    
    

Vue中的watchEffect:

  • 不需要手动声明依赖,简单高效,但依赖关系可能不够直观。
  • 适用于简单副作用场景,例如动态计算或直接响应所有相关数据变化。
  • vue响应是同步的,所以在watchEffect中async/await后面的异步代码中的依赖无法收集
    watchEffect(() => {
      console.log(state.value); // 自动将 state.value 加入依赖
    });
    
    

React中的useEffect:

  • 用于处理组件生命周期相关的副作用(如数据订阅、DOM 操作等)。
  • 通过依赖数组 [dependency] 显式声明监听的依赖项。
  • 可以清理副作用,通过返回一个函数来卸载或清理资源。
    useEffect(() => {
      console.log('Dependency changed');
    }, [dependency]);
    
    
3.依赖追踪方式

Vue

  • 自动依赖追踪(watchEffect
    • Vue 的响应式系统会动态追踪函数内部使用的所有响应式数据。
    • 例如:
      watchEffect(() => {
        console.log(state.value); // 自动将 state.value 加入依赖
      });
      
      
    • 原理:当 state.value 被读取时,Vue 的依赖追踪器(基于 Dep)会将当前副作用函数与该属性绑定。
  • 显式依赖声明(watch
    • 依赖由开发者显式指定:
      watch(() => state.value, (newVal) => {
        console.log(newVal);
      });
      
      
    • 原理:通过 getter 函数,明确指定哪些响应式数据需要触发回调。

React

  • 显式依赖声明
    • React 中依赖需要手动指定,React 不会动态追踪状态使用。
    • 例如:
      useEffect(() => {
        console.log('State value changed:', state.value);
      }, [state.value]);
      
      
    • 原理:React 比较依赖数组中的值(通过浅比较)。只有依赖值发生变化时,useEffect 才会重新执行。
4.总结
特性Vue `watch`Vue `watchEffect`React `useEffect`
依赖声明方式手动指定自动追踪手动指定
执行时机数据变化后初始化 & 数据变化后DOM 渲染后
适用场景复杂依赖、多数据监听简单自动副作用DOM 操作、副作用逻辑
优化难度中(需手动优化依赖)

拓展

Vue和React响应式比较

Vue 3

  • 基于 Proxy 的响应式系统
    • Vue 3 使用 JavaScript 的 Proxy 对象拦截对数据的访问和修改,实现响应式。
    • 数据的依赖关系通过 “依赖收集” 的方式自动建立,变化时会触发对应的渲染更新。
    • 响应式系统直接作用于数据层,开发者操作的普通对象会自动变成响应式。

React 18

  • 基于 Virtual DOM 和调度器
    • React 的响应式以状态管理为核心,借助 useStateuseReducer 等钩子函数实现状态的更新和追踪。
    • 状态变更会触发组件的重新渲染,并通过虚拟 DOM 比对(Diff 算法)计算出需要更新的部分,再应用到真实 DOM。
特性Vue 3React 18
响应式核心Proxy + 自动依赖追踪状态驱动 + 显式依赖管理
依赖追踪自动化、精确到属性级别依赖数组显式声明
状态管理响应式对象直接修改触发更新`useState` / `useReducer` 显式管理
渲染机制精确到数据属性的更新组件级渲染,通过虚拟 DOM 优化
性能优化自动依赖追踪 + 批量更新并发模式 + 虚拟 DOM 优化
使用复杂度简单易用,自动化高灵活性高,需手动优化

失去响应性

Vue

直接使用count.data是错误的,因为这个时候count.data被解构成了一个普通值,不再具有响应性。

//正确写法
watch(()=>count.data, (newValue, oldValue) => {
  console.log(newValue, oldValue); 
});

//错误写法
watch(count.data, (newValue, oldValue) => {
  console.log(newValue, oldValue);
});

React

React的响应性与Vue不同,React 更倾向于显式依赖声明,而 Vue 依赖于响应式系统,这里的count.data是一个普通变量,而只有setCount才能触发useEffect的监听

//正确写法
const [count, setCount] = useState({ data: 0 });
useEffect(() => {
  console.log('count.data changed:', count.data);
}, [count.data]);

//错误写法
const count = { data: 0 };
useEffect(() => {
  console.log('count.data changed:', count.data);
}, [count.data]);

http://www.kler.cn/a/429850.html

相关文章:

  • keepalived 各模式设置
  • 实时数据开发|Flink状态计算 有状态VS无状态,区别和优劣
  • NanoLog起步笔记-7-log解压过程初探
  • 什么是反向代理?作用、原理和实例详解
  • 反向代理-缓存篇
  • ubuntu22.04 使用可以用的镜像源获取你要的镜像
  • 数据结构与算法学习笔记----树与图的深度优先遍历
  • MACOS M1/M2芯片 Homebrew 安装教程
  • FastAPI解决跨域报错net::ERR_FAILED 200 (OK)
  • REDMI瞄准游戏赛道,推出小屏平板
  • 单片机C51--笔记8-STC89C51RC/RD-IIC协议
  • 太速科技-614-基于6U VPX FPGA VU9P 4路100G、32路10Gbps的光纤卡
  • 力扣第95题 不同的二叉搜索树 II
  • 【WebRTC】Android SDK使用教学
  • 如何使用靜態IP代理?【詳細教程】
  • 云原生周刊:在Docker上部署大语言模型
  • scala 身份证号码
  • hping3-网络工具
  • Brain.js(六):构建FNN神经网络实战教程 - 用户喜好预测
  • 鸿蒙实现后台任务管理