2026-10-19 10:47:39
useMemo和useCallback的核心区别在于:useMemo缓存计算结果的值,而useCallback缓存函数实例的引用,二者均用于React性能优化但适用场景不同。具体分析如下:
作用目标不同
useMemo:缓存计算结果的值。适用于需要避免重复计算的场景,例如对大型列表的排序、复杂数学运算结果或组件内需要多次使用的派生数据。
useCallback:缓存函数实例的引用。本质是useMemo(() => fn, deps)的语法糖,专门用于优化函数传递,避免因函数重新创建导致子组件不必要的渲染。
使用场景差异
useMemo的典型场景:
优化计算密集型操作:例如对1000条数据的过滤、排序或聚合计算。
避免重复生成稳定值:如固定格式的日期字符串、复杂对象的深拷贝结果。
依赖项变化时才重新计算:例如根据props.id和state.filter生成查询参数,仅当二者变化时重新计算。
useCallback的典型场景:
传递给子组件的函数:若子组件通过React.memo或shouldComponentUpdate优化,父组件函数重新创建会导致子组件无效更新。
事件处理函数依赖状态:例如onClick={() => setCount(c => c + 1)}可改写为useCallback避免每次渲染生成新函数。
函数作为依赖项:在useEffect或自定义Hook中,若依赖项包含内联函数会导致频繁执行,需用useCallback稳定引用。
依赖项(deps)的影响
两者均通过依赖项数组控制缓存更新:
当依赖项未变化时,返回缓存的值/函数实例。
依赖项变化时,重新计算值或创建新函数实例。
关键区别:useMemo的依赖项变化触发重新计算,而useCallback的依赖项变化触发新函数创建,但函数逻辑本身可能未变。
性能优化侧重点
useMemo:减少重复计算开销,优化CPU密集型任务。
useCallback:减少子组件渲染次数,优化渲染性能(尤其配合React.memo使用)。
注意事项:
过度使用可能增加内存压力(缓存未释放)。
简单计算或无性能问题时无需使用,避免过早优化。
依赖项需完整声明,否则可能导致闭包问题(如遗漏state或props)。
代码示例对比
// useMemo示例:缓存计算结果const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);// useCallback示例:缓存函数实例const memoizedCallback = useCallback(() => { doSomething(a, b);}, [a, b]);// 等价关系:useCallback(fn, deps) === useMemo(() => fn, deps)总结:二者本质均为React的性能优化工具,但useMemo针对值计算,useCallback针对函数实例。实际开发中需根据场景选择:若需缓存计算结果用useMemo,若需稳定函数引用避免子组件重渲染用useCallback。