React Hooks - useMemo 讲解及使用场景 ( 添加效果图 )
前言
如果你看过前面的useCallback
文章或者你已经会使用了,那么这篇useMemo
文章就会变得很简单,因为它两都是为了避免函数组件在更新值时重复创建问题。使用方式也都是差不多的。
useMemo
useMemo
的应用场景通常是在需要进行昂贵的计算或者运算量较大的逻辑处理时。比如,对于某些计算结果较为耗时的操作,我们可以使用 useMemo将计算结果缓存起来,避免重复计算,只在依赖项发生变化时重新计算。
语法格式:
useMemo 接收两个参数 ---> useMemo( ( ) => { ... } , [ ])
参数1:
接收一个函数,这个函数的返回值会作为useMemo的返回值
参数2:
接收一个数组,这个数组中包含了很多的元素,只有当这个数组中的元素发生了变化,useMemo才会重新计算
import { useMemo } form "react"
const name = useMemo( () => {
函数执行逻辑处理
return 返回值
}, [ 依赖项1, 依赖项2, ... ] )
场景假设:计算桃子和香蕉的总价格
不使用 useMemo 计算值遇到的问题
import React, { useState } from "react";
function App() {
const [likeCount, setLikeCount] = useState(2)
// 桃子的单价和价格
const [peach, setPeach] = useState({
num: 10,
unitPrice: 5
});
// 香蕉的单价和价格
const [banana, setBanana] = useState({
num: 10,
unitPrice: 10
});
// 1. 为了计算总的价格你可能会这样写
// const price = (peach.num * peach.unitPrice) + (banana.num * banana.unitPrice)
// 2. 还可能这样 在下面的dom中调用
const price = () => {
console.log("价格重新计算了--");
return (peach.num * peach.unitPrice) + (banana.num * banana.unitPrice)
}
const addLike = () => {
setLikeCount(likeCount + 1)
}
const change = () => {
setPeach({
...peach,
unitPrice: 20
})
}
return (
<div>
<h3>店铺点赞数:{likeCount}</h3>
<button onClick={addLike}>点赞</button>
<button onClick={change}>修改桃子的单价</button>
<h4> 购买的水果清单: </h4>
<h4> 桃子数量: {peach.num} 单价:{peach.unitPrice}元 </h4>
<h4> 香蕉数量: {banana.num} 单价:{banana.unitPrice}元 </h4>
{/* 1. 价格:{price}元 */}
总价:{price()}元
{/* 3. 还能这写· !!!
价格:{(peach.num * peach.unitPrice) + (banana.num * banana.unitPrice)}元
*/}
</div>
);
}
执行效果:
问题
- 可以看到不管是点赞,还是价格改变 总价计算函数(代码中三种方法都一样)都会执行。
- 案例中的计算量算小问题不大,那如果是
计算量较大,每次更新都需要大量计算,那界面的呈现时间就卡顿了
期望
- 点赞功能跟
计算总价
八杆子打不着,我们不希望它去影响水果的计算 - 那么
useMemo
的诞生就是为了这。
使用 useMemo 优化计算
import React, { useState , useMemo } from "react";
function App() {
const [introduction, setIntroduction] = useState("店长很懒什么都没写...")
// 桃子的单价和价格
const [peach, setPeach] = useState({
num: 10,
unitPrice: 5
});
// 香蕉的单价和价格
const [banana, setBanana] = useState({
num: 10,
unitPrice: 10
});
const change = () => { setIntroduction("这是一家水果店") }
const price = useMemo(()=>{
console.log("价格重新计算了--");
return (peach.num * peach.unitPrice) + (banana.num * banana.unitPrice)
},[peach,banana])
const addLike = () => {
setLikeCount(likeCount + 1)
}
const change = () => {
setPeach({
...peach,
unitPrice: 20
})
}
return (
<div>
<h3>店铺点赞数:{likeCount}</h3>
<button onClick={addLike}>点赞</button>
<button onClick={change}>修改桃子的单价</button>
<h4> 购买的水果清单: </h4>
<h4> 桃子数量: {peach.num} 单价:{peach.unitPrice}元 </h4>
<h4> 香蕉数量: {banana.num} 单价:{banana.unitPrice}元 </h4>
价格:{price}元
</div>
);
}
- 为
useMemo 添加依赖项
,只有在依赖项变动时 price 才会去计算,并把这次的计算结果给缓存下来
- 当依赖项之外的数据改变
useMemo就会从缓存里取值而不会重新计算
执行效果:
解决!现在点赞并不会影响价格计算了,只有在修改水果单价时才会去计算
最后
其实 useMemo 和 Vue 中的计算属性是一样
,都会将一个复杂计算的值给缓存。Vue 自动锁定依赖不需要你填写,React 把指定交给你来写。
小说一句
useCallback:
cosnt func = useCallback(()=>{ },[])
useMemo:
cosnt final = useMemo(()=>{ },[])
useEffect:
useEffect(()=>{ },[])
相同点:
它们第一个参数都是一个函数,第二个参数是一个数组可以添加多个依赖,依赖改变时(基本数据类型:值改变,引用数据类型:地址改变)就会执行第一个参数的函数。
不同点:
useCallBack - 需要返回一个函数 useMemo - 需要返回会值 useEffect - 多种不同的使用方法代表不同的含义
转载自:https://juejin.cn/post/7234006333484564539