理解 React 中的 useCallback
useCallback 钩子是什么
大家好,我们几乎已经讲完了 React.js 中最常用的 hooks。上篇文章我们讲解了useRef
hooks。这篇文章我们将讲解useCallback
hooks。那就让我们立即开始吧。
useCallback 钩子是什么
使用回调是一个钩子,当传递给它的一个依赖项发生变化时,它会返回一个记忆回调函数。
等等!这不就是 useMemo 所做的吗?
嗯,简而言之,答案是“不”!虽然这两个钩子都记忆了一些东西,但它们返回的内容却完全不同。useMemo 钩子返回一个记忆值,而 useCallback 返回一个记忆函数。
为什么useCallbacks
?
在创建应用程序时,钩子useCallback
非常有用,因为创建的一些函数很复杂,重新渲染组件可能会运行我们不想要的函数,可能是因为它可能会减慢运行时间。
让我们看看一些动作
此钩子接受一个回调函数(useCallback)和一个依赖项列表,当值改变时,该依赖项会使钩子运行。
基本用法
import { useCallback } from 'react';
const callbackVariable = useCallback(() => {
functionCall(a, b)
},[a, b]);
示例:
您可能会useCallback
同时使用钩子和useEffect
钩子。有时是为了防止持续的重新渲染或无限循环。请参考下方沙盒中的示例。
在上面的例子中,我使用了两个组件:App.js
file 和Score.js
file。score 组件有一个 useEffect,它会在 props 发生变化时更新状态,并在控制台上记录一条消息。
import React, { useEffect, useState } from "react";
const Score = ({ score }) => {
const [showScore, setShowScore] = useState();
useEffect(() => {
setShowScore(score());
console.log("Component updating");
}, [score]);
return (
<div>
<div>Score here: {showScore}</div>
</div>
);
}
export default Score;
在这个App.js
文件中,我们有一个clacScore
函数,用于将用户输入的任何分数加 5,一个输入字段,用于输入玩家姓名,以及一个按钮,用于切换玩家姓名。一切看起来都运行正常,不是吗?
我们的代码有个问题。当我们在输入框中输入玩家姓名时,控制台会打印一条消息,而且我们在页面上进行任何操作时也会打印一条消息。这很麻烦,因为我们只想在更新比分时显示这条消息。
useCallback 来救援
尝试clacScore
用下面的代码替换该函数。
const clacScore = useCallback(() => {
return(scoreEntered * 5);
}, [scoreEntered]);
现在尝试在输入框中输入玩家姓名或显示玩家姓名。请注意,控制台中的消息仅在我们更改分数时显示。这是因为我们使用useCallback
钩子来告诉 React 仅在状态更新Score
时渲染组件scoreEntered
。因此,钩子实际上帮助我们提升了小应用程序的性能。
什么时候应该使用回调?
所以我相信大家都同意 useCallback 很棒。然而,这并不意味着我们应该把所有函数都包装到 useCallback 里,记住那句话:
凡事过量都是不好的。
是的,这适用于useCallback
和useMemo
和useAnything
(等等!什么?😅)。
因此 useCallback 钩子应该只在以下情况下使用:
-
我们希望进行引用相等性(因为 JavaScript 将函数视为对象,并且在 JavaScript 中测试对象之间的相等性相当麻烦)
-
当我们有一个复杂的函数时(即该函数的计算成本很高)。
结论
无关,但还记得《正义联盟》里他们必须让超人复活的那个场景吗?他们有一个完美的理由让他复活。同样的逻辑也适用于此。引入 useCallback 意味着我们已经在代码中引入了一些复杂性,所以我们应该有一个完美的理由在代码中使用 useCallback。
非常感谢你的阅读。下一部分我们将讲解useReducer
钩子。如果你有任何贡献或意见,请在下方评论区留言。也请关注我,获取更多类似内容,并注意安全。