请别用Vue的方式使用React的响应式数据

请别用Vue的方式使用React的响应式数据

写在前面

最近一周,我简单学习了一下 React 全家桶。由于有 Vue 的基础,我迅速上手了 React、Redux 和 React Router,并直接在新项目中实践。

在学习过程中,我常常把 Vue 的相应功能进行类比,因此在使用 React 的响应式数据时,习惯用 Vue 的思维方式。这导致了一些细节处理上的问题。

我查阅了一些资料,整理了一些心得(或许不完全准确),在此记录并分享。

数据的创建和更新

在 Vue 3 中,通常使用 ref 来定义响应式数据,而在 React 中,使用 useState 创建数据,并通过 setState 更新数据。

Vue 3 的数据更新是通过 Proxy 拦截数据的修改来实现的,从而更新视图。

React 则需要手动调用相应的 setState 方法来更新视图。

界面中的响应式数据

在 Vue 3 中,如果某个响应式数据存在于组件的 template 中(例如:<div>{{num + 1}}</div>),Vue 会在首次渲染时将其绑定到依赖收集中。当响应式数据发生变化时,Vue 会自动检测到并更新视图。

在 React 中,组件是纯函数的概念。当组件的 props 或 state 发生变化时,整个函数组件会重新调用。这意味着所有在函数内声明的变量和表达式都会重新计算,最终由 React 根据新的计算结果更新视图。

因此,React 中函数的内容会被频繁执行,而在 Vue 3 的组合式 API(setup)中,内容通常只执行一次。

数据缓存

Vue 3 中有 computed,而 React 中有 useMemo。

共同点

两者都是用于优化性能,避免不必要的计算和渲染。只有在依赖的数据变化时才会重新计算。

不同点

computed(Vue 3)

computed 用于声明性地定义依赖响应式数据的计算属性。计算属性会根据依赖的数据变化自动重新计算,并且结果会被缓存。计算属性也是一个响应式的数据(类似于 ref)。

计算属性默认是惰性计算的,只有在其结果被访问时才会计算一次,并在依赖数据不变时,后续访问直接返回缓存的结果。

useMemo(React)

useMemo 用于在函数组件中缓存计算密集的值。只有当依赖项数组中的某个值发生变化时,才会重新计算。它常用于优化计算开销较大的操作或避免不必要的子组件重新渲染(例如,当多个 state 的计算结果作为 props 传递给子组件时,如果 state 变化但 useMemo 返回值不变,子组件不会重新渲染)。

useMemo 在组件渲染期间执行,依赖项未变化时返回之前的缓存值。与 computed 的惰性计算不同,useMemo 是在组件渲染时计算的。

总的来说,useMemo 和 computed 的使用目的有些不同。由于函数组件可能频繁渲染(任何依赖的 state 或 props 变化都会触发重新执行),useMemo 可以显著减少不必要的重新计算。只要在 useMemo 中设定所需的依赖项,就能有效优化性能。

最后

总结来说,我最大的错误就是把 useMemo 当成 computed 来用了。

由于 React 函数组件的特性,有些情况下没有必要使用 useMemo 来维持数据的响应式。只有当计算开销较大时,才需要使用 useMemo 来优化性能。

文章封面来自 AI 绘图(Draw Things - DreamShaper 模型)

作者

AkiChase

发布于

2024-07-30

更新于

2024-07-30

许可协议