用法
useMemo和useCallback接收的参数都是一样,第一个参数为回调,第二个参数为要依赖的数据
共同作用:1. 仅仅依赖数据发生变化,才会重新计算结果,也就是起到缓存的作用。
俩者区别:1. useMemo计算结果是return回来的值,主要用于缓存结果的值,应用场景如:需要计算的状态。
2. useCallback计算结果是函数,主要用于缓存函数,应用场景如:需要缓存的函数,因为函数式组件每次任何一个state的变化整个组件都会被重新刷新,一些函数是没有必要被重新刷新的,此时就应该缓存起来,提高性能,和减少资源浪费。
useCallback
代码示例
import React, { useEffect, useState, useCallback, useMemo } from 'react';
const App = () => {
const [count, setCount] = useState(0);
const handleCountAddByCallBack = useCallback(() => {
setCount((count) => count + 1);
}, []);
const handleCountAdd = () => {
setCount((count) => count + 1);
};
return (
<>
<h3>CountAddByChild1: {count}</h3>
<Child1 addByCallBack={handleCountAddByCallBack} add={handleCountAdd} />
</>
)
}
const Child1 = ({ addByCallBack, add}) => {
useEffect(() => {
console.log("Child1----addFcUpdate");
}, [add])
useEffect(() => {
console.log("Child1----addByCallBackFcUpdate");
}, [addByCallBack])
return (
<div>
<Button onClick={add}>+1</Button>
<br />
<Button onClick={addByCallBack}>+1(addByCallBack)</Button>
</div>
)
}
useMemo
代码示例
const Child1 = () => {
const [count, setCount] = useState(0);
const [total, setTotal] = useState(0);
const countToString = (() => {
console.log("countToString 被调用");
return count.toString();
})();
const totalToStringByMemo = useMemo(() => {
console.log("totalToStringByMemo 被调用");
return String(total);
}, [total]);
return (
<div>
<h3>countToString: {countToString}</h3>
<h3>countToString: {totalToStringByMemo}</h3>
<Button
onClick={() => {
setCount((count) => count + 1);
}}
>
Add Count
</Button>
<br />
<Button
onClick={() => {
setTotal((total) => total + 1);
}}
>
Add Total
</Button>
</div>
)
}
小结
- useCallBack针对可能重新创建的函数进行优化,使得函数被缓存,React.memo认定俩次地址是相同就可以避免子组件冗余的更新。
- useMemo针对不必要的计算进行优化,避免了当前组件中一些冗余计算操作。