react useMemo和 useEffect和 useCallback
useEffect
effect只能在DOM更新后触发
useMemo
传入 useMemo 的函数会在渲染期间执行,即在DOM更新前触发的,就像官方所说的,类比生命周期就是shouldComponentUpdate
useMemo和useCallback都会在组件第一次渲染的时候执行,之后会在其依赖的变量发生改变时再次执行;
useCallback
useCallback跟useMemo比较类似,但它返回的是缓存的函数。
代码语言:javascript复制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
记住一个模板的子树。元素和组件上都可以使用。该指令接收一个固定长度的数组作为依赖值进行记忆比对。如果数组中的每个值都和上次渲染的时候相同,则整个该子树的更新会被跳过
代码语言:javascript复制<div v-memo="[valueA]">
...
</div>
当组件重新渲染的时候,如果valueA都维持不变,那么对这个<div>以及它的所有子节点的更新都将被跳过。事实上,即使是虚拟 DOM 的 VNode 创建也将被跳过,因为子树的记忆副本可以被重用。
使用场景
假设请求接口返回来了1000 条数据。 前端需要做筛选。 选出符合条件的数据进行展示。 如果没有符合条件的。则保持上次的展示。
代码语言:javascript复制<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