虽然说之前已经认识了 useCallback、useMemo,但有时还是对於什麽时候要用它们的时机有些模糊,所以就透过这篇文章厘清观念。
首先要知道一点是如果没有必要可以不用去用它们,盲目的使用反而更耗效能,因为它们在 React 底层记忆值也是需要消耗效能的。
在此先复习一下 Referential Equality,对於理解後面的内容会有所帮助。
我们知道阵列、物件、函式等物件型别拥有 call by reference 的特性,所以即使有两个物件它们里面的元素、属性、函式内容都一样,在做 ===
比较时仍然会是 false。
const hero1 = {
name: 'Batman'
};
const hero2 = {
name: 'Batman'
};
console.log(hero1 === hero1); // => true
console.log(hero1 === hero2); // => false
这样跟 React 又有什麽关系?让我们继续看下去!
在下面的范例可以看到一个被 React.memo() 包覆的元件 Child,而且接收到一个函式 onClick 当作 props。
父元件重新渲染时,虽然都还是同一个函式,但函式被重新产生了,所以 React.memo() 会以为传入的 props 改变而重新渲染 Child 元件,所以加上了 useCallback。
function Parent() {
const [count, setCount] = useState(0);
const onClick = useCallback(() => {
console.log('click');
}, []);
return (
<>
<Foo onClick={onClick} />
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>count increment</button>
</>
);
}
const Child = memo({ onClick }) => {
// ...略
return (
<>
// ...
<button onClick={onClick}>可点击</button>
</>
)
});
useEffect 的 dependency array 的其中一个元素为物件型别时,若物件重新产生就会被 useEffect 当作 dependency array 改变,像以下的例子就造成了 useEffect 无限 render,所以也需要加上 useCallback。
跟此范例类似的例子在 pjchender 大大的 从 Hooks 开始,让你的网页 React 起来 Day20 篇 也有提到,有兴趣的读者可以跳到"在 useEffect 的 dependencies 中放入函式 - useCallback 的使用"的段落去阅读。
const App = () => {
const [id, setId] = useState(1);
const [detail, setDetail] = useState("");
const getDetail = useCallback(() => {
fetch(`https://jsonplaceholder.typicode.com/users/${id}`)
.then(res => res.json())
.then(json => {
setDetail(json); // state updated
}));
}, [id]);
useEffect(() => {
getDetail();
}, [getDetail]);
return (
<>
<p>{detail.name}</p>
<p>Current id: {id}</p>
<button onClick={() => setId(id + 1)}>id increment</button>
</>
);
}
Referential Equality 的概念也可以套用在 useMemo,所以也可以留意一下 useEffect 的 dependency array。
const App = ({ param1, param2 }) => {
const params = useMemo(() => {
return { param1, param2, param3: 1 };
}, [param1, param2]);
useEffect(() => {
callApi(params);
}, [params]);
}
例如 filter 很多元素的阵列、复杂数学运算
How To Use Memoization To Drastically Increase React Performance
When to useMemo and useCallback
如何错误地使用 React hooks useCallback 来保存相同的 function instance
为什麽要补充? 当决定铁人赛的题目是 Design Patterns 时,除了先 Google 看看...
这个得上一篇在https://ithelp.ithome.com.tw/articles/10257...
ASP.NET网页切换导向及状态管理-趴水 今天来做做看 在网页输入资料後 按下按钮 可以将资料导向...
上一篇提到下了 tsc --init 指令之後会创建出一个 tsconfig.json 的档案,这个...
混入 Mixins 当我们在编写 css 时,常常会发现有要重复套用的地方,像是一个网站的主题样式,...