zl程序教程

您现在的位置是:首页 >  前端

当前栏目

react useMemo、useEffect和 useCallback区别及与 vue 对比

VueReact 区别 对比 useEffect useMemo useCallback
2023-06-13 09:11:03 时间

react useMemo和 useEffect和 useCallback

useEffect

effect只能在DOM更新后触发

useMemo

传入 useMemo 的函数会在渲染期间执行,即在DOM更新前触发的,就像官方所说的,类比生命周期就是shouldComponentUpdate

useMemo和useCallback都会在组件第一次渲染的时候执行,之后会在其依赖的变量发生改变时再次执行;

useCallback

useCallback跟useMemo比较类似,但它返回的是缓存的函数。

const fnA = useCallback(fnB, [a])

上面的useCallback会将我们传递给它的函数fnB返回,并且将这个结果缓存;当依赖a变更时,会返回新的函数。既然返回的是函数,我们无法很好的判断返回的函数是否变更,所以我们可以借助ES6新增的数据类型Set来判断.

使用场景:

  • 有一个父组件,其中包含子组件,子组件接收一个函数作为props;通常而言,如果父组件发生任何更新,子组件也同样会执行一次重新渲染,而当父组件的 callback 没有变化时,子组件依赖的props中的 callback 也再次更新就是没有必要的,所以我们可以借助useCallback来返回函数,然后把这个函数作为props传递给子组件;这样,子组件就能避免不必要的更新,优化渲染性能;
  • 所有依赖本地状态或props来创建函数,需要使用到缓存函数的地方

总结:useMemo和useCallback这两个hooks都返回缓存的值,useMemo返回缓存的变量,useCallback返回缓存的函数

参考:https://blog.csdn.net/hsany330/article/details/106122228

https://blog.csdn.net/sinat_17775997/article/details/94453167

react useMemo和 vue computed

https://blog.csdn.net/weixin_43720095/article/details/104950676 react useMemo类似 vue 的 computed,不要在这个函数内部执行与渲染无关的操作,诸如副作用这类的操作属于 useEffect 的适用范畴,而不是 useMemo

把“创建”函数和依赖项数组作为参数传入 useMemo,避免不必要的执行渲染,以达到优化性能的目的

  • 缓存计算结果的值
  • 计算结果是 return 的值

Vue v-memo

记住一个模板的子树。元素和组件上都可以使用。该指令接收一个固定长度的数组作为依赖值进行记忆比对。如果数组中的每个值都和上次渲染的时候相同,则整个该子树的更新会被跳过

<div v-memo="[valueA]">
  ...
</div>

当组件重新渲染的时候,如果valueA都维持不变,那么对这个<div>以及它的所有子节点的更新都将被跳过。事实上,即使是虚拟 DOM 的 VNode 创建也将被跳过,因为子树的记忆副本可以被重用。

使用场景

假设请求接口返回来了1000+条数据。 前端需要做筛选。 选出符合条件的数据进行展示。 如果没有符合条件的。则保持上次的展示。

<template>
  <div class="home">
    <input type="text" v-model="food">
    <!-- v-memo中“valueA”若不发生变化,则不会进行更新 -->
    <div v-memo="[valueA]">
      <div class="box" v-for="item in arr" :key="item">  {{ foodObj[food] }}  </div>
    </div>
  </div>
</template>
<script setup>
import { ref, watch } from "vue"

// 先生成1000条数据
const arr = new Array(1000)

// 定义一个对象
const foodObj = {
  'hb':' ',
  'nc':' ',
  'st':' ',
}

// input绑定的值
const food = ref('hb')

// v-memo依赖的值
const valueA = ref(0)

// 如果数据发生变化,并且在foodObj对象中存在。视图进行更新。否则视图不更新。
watch(()=>food.value,()=>{
  if(Object.keys(foodObj).includes(food.value)){
    valueA.value = Math.ceil(Math.random()*10000)
  }
})
</script>

<style>
.box {
   display: inline-block;
   width: 80px;
}
</style>

注意点

v-for内部使用v-memo是无效的。

参考:https://zhuanlan.zhihu.com/p/531870129