区别概览
- | useCallBack | useMemo |
---|---|---|
返回值 | 一个缓存的回调函数 | 一个缓存的值 |
参数 | 需要缓存的函数,依赖项 | 需要缓存的值(也可以是个计算然后再返回值的函数) ,依赖项 |
使用场景 | 父组件更新时,通过props传递给子组件的函数也会重新创建,然后这个时候使用 useCallBack 就可以缓存函数不使它重新创建 | 组件更新时,一些计算量很大的值也有可能被重新计算,这个时候就可以使用 useMemo 直接使用上一次缓存的值 |
useCallBack 具体示例
import React, { useCallback, useEffect, useState } from "react";
import "./styles.css";
export default function App() {
const [count, setCount] = useState(0);
// 使用 useCallBack 缓存
const handleCountAddByCallBack = useCallback(() => {
setCount((count) => count + 1);
}, []);
// 不缓存,每次 count 更新时都会重新创建
const handleCountAdd = () => {
setCount((count) => count + 1);
};
return (
<div className="App">
<h3>CountAddByChild1: {count}</h3>
<Child1 addByCallBack={handleCountAddByCallBack} add={handleCountAdd} />
</div>
);
}
const Child1 = React.memo(function (props) {
const { add, addByCallBack } = props;
// 没有缓存,由于每次都创建,memo 认为两次地址都不同,属于不同的函数,所以会触发 useEffect
useEffect(() => {
console.log("Child1----addFcUpdate", props);
}, [add]);
// 有缓存,memo 判定两次地址都相同,所以不触发 useEffect
useEffect(() => {
console.log("Child1----addByCallBackFcUpdate", props);
}, [addByCallBack]);
return (
<div>
<button onClick={props.add}>+1</button>
<br />
<button onClick={props.addByCallBack}>+1(addByCallBack)</button>
</div>
);
});
useMemo 示例
import { useState, useMemo } from "react";
import "./styles.css";
export default function App() {
const [count, setCount] = useState(0);
const [total, setTotal] = useState(0);
// 没有使用 useMemo,即使是更新 total, countToString 也会重新计算
const countToString = (() => {
console.log("countToString 被调用");
return count.toString();
})();
// 使用了 useMemo, 只有 total 改变,才会重新计算
const totalToStringByMemo = useMemo(() => {
console.log("totalToStringByMemo 被调用");
return total + "";
}, [total]);
return (
<div className="App">
<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 针对不必要的计算进行优化,避免了当前组件中一些的冗余计算操作。
转载自:https://www.jianshu.com/p/b8d27018ed22