对useMemo
的理解
下面这个例子是想在页面上实时的显示出expensive
函数的计算结果,但按照之前的写法,useState
中任意的值发生改变时,页面都会重新渲染,导致昂贵的计算函数expensive
会进行多余计算。
这个例子中无论是val
还是count
发生改变,函数都会运算一遍,但我们只想在count
的值发生改变时才进行这个昂贵计算,因此就要用到useMemo
。
import React, { useState, useMemo } from "react";
export default function App() {
const [count, setCount] = useState(1);
const [val, setValue] = useState("");
function expensive() {
console.log("compute");
// 非常昂贵的计算
// 无论更新 val还是count 都会重新计算
let sum = 0;
for (let i = 0; i < count * 100; i++) {
sum += i;
}
return sum;
}
return (
<div>
<h4>count:{count}</h4>
<h4>val:{val}</h4>
<h4>{expensive()}</h4>
<div>
<button onClick={() => setCount(count + 1)}>count+1</button>
<input value={val} onChange={(event) => setValue(event.target.value)} />
</div>
</div>
);
}
使用useMemo
之后,expensive
函数就只在count
发生改变时才进行运算,并且也会实时的显示在页面上。
import React, { useState, useMemo } from "react";
export default function App() {
const [count, setCount] = useState(1);
const [val, setValue] = useState("");
//使用useMemo就可以仅在依赖项改变时才进行计算,避免多余计算
const expensive = useMemo(() => {
let sum = 0;
for (let i = 0; i < count * 100; i++) {
sum += i;
}
return sum;
}, [count])
return (
<div>
<h4>count:{count}</h4>
<h4>val:{val}</h4>
<h4>{expensive}</h4>
<div>
<button onClick={() => setCount(count + 1)}>count+1</button>
<input value={val} onChange={(event) => setValue(event.target.value)} />
</div>
</div>
);
}
总结:如果我们即想在网页上实时的显示函数计算结果,又不想由于其他无关useState
变量的改变而重新渲染页面进而重新计算函数,出现多余计算,造成浪费,我们就可以用useMemo
来达到自己想要的结果,即仅在相关参数发生改变时,函数才重新运算,并将页面上的结果重新渲染进行更新。
与useEffect
的区别
这里疑惑了很久,刚开始以为作用和useEffect
是一样的
因为书写形式和调用机制很像:都传入了一个函数,都在关联变量发生改变时才去执行
但其实区别很大:useEffect
没有返回值(在不考虑解绑的情况下),并且是在页面渲染之后才执行的,而useMemo
有返回值,并且是在页面渲染的时候进行的