官方定义
useMemo是一个React Hook,它在每次重新渲染的时候能够缓存计算结果
这里包含了两个信息
useMemo作用:缓存计算结果
useMemo生效的时机:重新渲染的时候
那么哪些情况会重新渲染呢?
1、组件的state发生变化
2、传入组件的props发生变化
3、父组件重新渲染
看一下下面这段代码
import React, {useState, useMemo} from 'react';
const mock_data = Array(5000000).fill(null).map((_,i)=>({
score:i,
name: i + '号选手'
}))
const UseMemoDemo = () => {
const [count, setCount] = useState(0)
const sum = () => {
console.log('看看触发了没')
return eval(mock_data.map(item=>item.score).join('+'))
}
return (
<div>
<p>count:{count}</p>
<button onClick={()=>{setCount(count+1)}}>点击加一</button>
总分:{sum()}
</div>
)
}
export default UseMemoDemo;
可以看到当你点击按钮的时候,sum也在持续触发中,此时由于sum中的计算量过大,造成了明显的卡顿现象
用useMemo改造后,如下:
import React, {useState, useMemo} from 'react';
const mock_data = Array(5000000).fill(null).map((_,i)=>({
score:i,
name: i + '号选手'
}))
const UseMemoDemo = () => {
const [count, setCount] = useState(0)
const sum = useMemo(() => {
console.log('看看触发了没')
return eval(mock_data.map(item=>item.score).join('+'))
},[])
return (
<div>
<p>count:{count}</p>
<button onClick={()=>{setCount(count+1)}}>点击加一</button>
总分:{sum}
</div>
)
}
export default UseMemoDemo;
此时,count的变化就影响不到sum了,另外有一点要注意,此时的sum是单纯的一个数值,不是函数,useMemo的返回值是一个计算结果!!
这里看一下useMemo的结构:
const cachedValue = useMemo(calculateValue, dependencies)
一个没有任何参数的 calculation 函数,像这样 () =>,并且返回任何你想要的计算结果。
一个由包含在你的组件中并在 calculation 中使用的所有值组成的 依赖列表。
useMemo缓存的值(cachedValue)就是其第一个参数,即calculateValue函数的返回值
第二个参数是依赖项,类似于useEffect的用法,可以看一下下面的代码
import React, {useState, useMemo} from 'react';
const mock_data = Array(50000).fill(null).map((_,i)=>({
score:i,
name: i + '号选手'
}))
const UseMemoDemo = () => {
const [count, setCount] = useState(0)
const [trigger, setTrigger] = useState(true)
const sum = useMemo(() => {
if(trigger){
return eval(mock_data.map(item=>item.score).join('+'))
}else{
return "算不出来"
}
},[trigger])
return (
<div>
<p>count:{count}</p>
<p>
<button onClick={()=>{setCount(count+1)}}>点击加一</button></p>
总分:{sum}
<p>
<button onClick={()=>{setTrigger(!trigger)}}>只有点击我的时候,sum才受影响</button>
</p>
</div>
)
}
export default UseMemoDemo;
可以看到效果,sum只受到trigger这个状态的影响,其余的状态都不会更新它