一、useCallback
的作用与使用场景总结
useCallback
是 React 提供的一个 Hook,用于缓存函数的引用,避免因为组件重新渲染而导致函数地址发生变化。- 它返回一个记忆(memoized)后的回调函数,只有当依赖项发生变化时才会重新生成该函数。
二、具体讲解与使用场景
(一)作用详解
- (1) 避免函数在每次渲染时都重新创建
- React 函数组件每次渲染都会重新定义所有函数,可能会导致不必要的渲染或性能浪费。
- (2) 与子组件配合
React.memo
使用,避免子组件不必要的渲染- 如果 props 中有一个函数,每次渲染都会创建新函数引用,即使函数体一样,也会导致子组件更新。
(二)使用场景
- (1) 传递函数给使用
React.memo
的子组件时,避免子组件重复渲染。 - (2) 用于依赖函数的
useEffect
、useMemo
,如果不缓存函数会导致无限循环或性能问题。 - (3) 用于性能优化较敏感的场景,避免重复创建函数。
三、代码示例
(一)未使用 useCallback
导致子组件重复渲染
jsx
import React, { useState } from 'react';
const Child = React.memo(({ onClick }) => {
console.log("Child Rendered");
return <button onClick={onClick}>Click Me</button>;
});
const Parent = () => {
const [count, setCount] = useState(0);
const handleClick = () => {
console.log("Clicked");
};
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Add</button>
<Child onClick={handleClick} />
</div>
);
};
- 每次点击"Add",
Parent
组件会重新渲染,handleClick
是新函数,导致Child
被重新渲染。
(二)使用 useCallback
缓存函数,优化渲染
jsx
import React, { useState, useCallback } from 'react';
const Child = React.memo(({ onClick }) => {
console.log("Child Rendered");
return <button onClick={onClick}>Click Me</button>;
});
const Parent = () => {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log("Clicked");
}, []); // 空数组表示 handleClick 永远不会变
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Add</button>
<Child onClick={handleClick} />
</div>
);
};
- 此时点击"Add"不会触发
Child
重新渲染,提升性能。
四、小结
useCallback(fn, deps)
等价于useMemo(() => fn, deps)
- 用于性能优化,不是所有场景都需要用
- 优先考虑组件中是否存在性能瓶颈,再考虑是否引入
useCallback