手册
目录
收藏216
分享
阅读2239
更新时间2025-08-20
React useCallback Hook 返回一个记忆化的回调函数。
将记忆化视为缓存一个值,以便不需要重新计算。
这使我们能够隔离资源密集型函数,以便它们不会在每次渲染时自动运行。
useCallback Hook 仅在其依赖项之一更新时运行。
这可以提高性能。
useCallback 和 useMemo Hooks 类似。
主要区别在于 useMemo 返回一个记忆化的 value 而 useCallback 返回一个记忆化的 函数。
您可以在 useMemo 章节中了解更多关于 useMemo 的信息。
使用 useCallback 的一个原因是防止组件重新渲染,除非其 props 已更改。
在这个例子中,你可能认为 Todos 组件不会重新渲染,除非 todos 改变:
这与 React.memo 部分中的示例类似。
index.js
import { useState } from "react";
import ReactDOM from "react-dom/client";
import Todos from "./Todos";
const App = () => {
const [count, setCount] = useState(0);
const [todos, setTodos] = useState([]);
const increment = () => {
setCount((c) => c + 1);
};
const addTodo = () => {
setTodos((t) => [...t, "New Todo"]);
};
return (
<>
Count: {count}
>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render( );
Todos.js
import { memo } from "react";
const Todos = ({ todos, addTodo }) => {
console.log("child render");
return (
<>
My Todos
{todos.map((todo, index) => {
return {todo}
;
})}
>
);
};
export default memo(Todos);
运行实例 »
尝试运行它并单击计数增量按钮。
您会注意到,即使 todos 没有更改,Todos 组件也会重新渲染。< /p>
为什么这不起作用? 我们使用的是 memo,所以 Todos 组件不应该重新渲染,因为当计数增加时,todos 状态和 addTodo 函数都不会改变。
这是因为所谓的"参照平等"。
每次重新渲染组件时,都会重新创建其功能。 正因为如此,addTodo 函数实际上发生了变化。
为了解决这个问题,我们可以使用 useCallback hook 来防止函数被重新创建,除非必要。
使用 useCallback Hook 来防止 Todos 组件不必要地重新渲染:
index.js
import { useState, useCallback } from "react";
import ReactDOM from "react-dom/client";
import Todos from "./Todos";
const App = () => {
const [count, setCount] = useState(0);
const [todos, setTodos] = useState([]);
const increment = () => {
setCount((c) => c + 1);
};
const addTodo = useCallback(() => {
setTodos((t) => [...t, "New Todo"]);
}, [todos]);
return (
<>
Count: {count}
>
);
};
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render( );
Todos.js
import { memo } from "react";
const Todos = ({ todos, addTodo }) => {
console.log("child render");
return (
<>
My Todos
{todos.map((todo, index) => {
return {todo}
;
})}
>
);
};
export default memo(Todos);
运行实例 »
现在 Todos 组件只会在 todos 属性改变时重新渲染。
相关
视频
RELATED VIDEOS
科技资讯
1
2
3
4
5
6
7
8
9
精选课程
共5课时
17.2万人学习
共49课时
77.1万人学习
共29课时
61.8万人学习
共25课时
39.4万人学习
共43课时
71万人学习
共25课时
61.7万人学习
共22课时
23万人学习
共28课时
33.9万人学习
共89课时
125.2万人学习