请别用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 模型)
请别用Vue的方式使用React的响应式数据