React:useCallback和useMemo区别? 具体使用场景?
useCallback
和useMemo
是React提供的两个Hook,用于优化函数组件的性能。它们都有助于避免不必要的重新渲染和计算,但它们的用途和工作原理有所不同。
useCallback
useCallback
返回一个记忆化的回调函数。这意味着只有在依赖项发生变化时,React才会重新创建这个函数。useCallback
的主要目的是避免在每次渲染时重新创建相同的回调函数,从而防止子组件不必要的重新渲染。
语法
const memoizedCallback = useCallback(() => {
doSomething(a, b);
}, [a, b]);
使用场景
- 传递回调函数给子组件:
当一个子组件依赖于父组件传递的回调函数时,如果父组件每次渲染都创建新的回调函数,子组件会每次重新渲染。使用
useCallback
可以避免这种情况。
import React, { useState, useCallback } from 'react';
const ChildComponent = React.memo(({ onClick }) => {
console.log('ChildComponent rendered');
return <button onClick={onClick}>Click me</button>;
});
const ParentComponent = () => {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log('Button clicked');
}, []);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
<ChildComponent onClick={handleClick} />
</div>
);
};
export default ParentComponent;
在这个例子中,ChildComponent
只有在handleClick
改变时才会重新渲染。
useMemo
useMemo
返回一个记忆化的值。它的主要目的是避免在每次渲染时进行昂贵的计算,只在依赖项发生变化时才重新计算值。
语法
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
使用场景
- 避免昂贵的计算:
当一个计算过程非常耗时,而这个计算在依赖项不变的情况下结果也不会变化时,使用
useMemo
可以提高性能。
import React, { useState, useMemo } from 'react';
const computeExpensiveValue = (num) => {
console.log('Computing expensive value');
let result = 0;
for (let i = 0; i < 1000000000; i++) {
result += num;
}
return result;
};
const MyComponent = () => {
const [count, setCount] = useState(0);
const [input, setInput] = useState('');
const expensiveValue = useMemo(() => computeExpensiveValue(count), [count]);
return (
<div>
<input value={input} onChange={e => setInput(e.target.value)} />
<p>Count: {count}</p>
<p>Expensive Value: {expensiveValue}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default MyComponent;
在这个例子中,computeExpensiveValue
函数只在count
改变时重新计算,避免了不必要的计算。
区别总结
-
返回值:
useCallback
返回一个记忆化的回调函数。useMemo
返回一个记忆化的值。
-
用途:
useCallback
用于记忆化回调函数,避免在组件重新渲染时重复创建相同的函数。useMemo
用于记忆化计算结果,避免在组件重新渲染时重复进行昂贵的计算。
-
依赖数组:
- 两者都接受一个依赖数组,当数组中的依赖项发生变化时,React会重新计算返回的函数或值。
使用建议
- 使用
useCallback
:当需要将函数作为属性传递给子组件,且该子组件对函数变化敏感时使用useCallback
。 - 使用
useMemo
:当需要进行昂贵的计算,并且该计算的结果在多次渲染中可以复用时使用useMemo
。
通过合理使用useCallback
和useMemo
,可以显著提高React应用的性能,减少不必要的重新渲染和计算开销。
转载自:https://juejin.cn/post/7380730718295982090