useMemo
import { useMemo } from 'react';
function MyComponent({ a, b }) {
const memoizedValue = useMemo(() => {
// 进行一些昂贵的计算
return a + b;
}, [a, b]); // 当 a 或 b 发生变化时,memoizedValue 将被重新计算
return <div>{memoizedValue}</div>;
}
useMemo
接受两个参数:一个函数和一个依赖数组。函数返回我们想要“记住”的值,而依赖数组则告诉 React 何时需要重新计算这个值。
注意事项
1、useMemo
仅在依赖项发生变化时重新计算值。如果依赖项没有变化,即使组件重新渲染,useMemo
也会返回上一次缓存的值。
2、useMemo
缓存的是函数的返回值,而不是函数本身。因此,如果函数本身发生变化(例如,函数内部的逻辑被修改),即使依赖项没有变化,useMemo
也可能会返回新的值。但这种情况在实际开发中较少见,因为函数逻辑通常在组件外部定义且不会频繁变化。
3、在使用 useMemo
时,需要注意不要过度优化。对于一些简单的计算或不会频繁触发的计算,可能不需要使用 useMemo
。因为过度使用 useMemo
可能会增加内存的消耗,并可能导致不必要的复杂性。
useCallback
useCallback
的主要作用是返回一个缓存版本的函数,只有当它的依赖项发生变化时,这个函数才会被重新创建。这意味着,如果依赖项没有改变,函数的引用将保持不变,从而避免因函数引用改变而导致的不必要的重新渲染。其背后的原理是利用闭包和 React 的调度机制来存储并在必要时重建函数。
useCallback
接受两个参数:一个是要被缓存的回调函数,另一个是该回调函数的依赖项数组。当依赖项数组中的任何一个值发生变化时,useCallback
都会返回一个新的函数实例;否则,它将返回之前缓存的函数实例。
const memoizedCallback = useCallback(() => {
doSomething(a, b);
}, [a, b]);
在这个例子中,memoizedCallback
是一个被缓存的函数,它仅在 a
或 b
发生变化时才会被重新创建。
使用场景
1、在传递给子组件的回调函数中,特别是当子组件使用了如 React.memo
或 shouldComponentUpdate
来避免不必要的渲染时,useCallback
可以确保传递给子组件的回调函数引用保持稳定,从而防止不必要的重新渲染。
2、在大型列表渲染或频繁状态更新的性能敏感场景中,使用 useCallback
可以帮助提升性能。
注意事项
1、与直接在组件内创建函数相比,使用 useCallback
需要付出额外的开销,因为它涉及到存储和检索函数的机制。因此,在不需要优化性能的情况下,盲目使用 useCallback
可能会导致性能下降。
2、依赖项数组应准确反映函数的所有外部依赖,以避免出现逻辑错误。未来编译器可能会更加智能,能够自动创建和管理依赖项数组。