2026-07-14 22:11:24
useCallback 的目的不是直接防止组件渲染,而是通过避免函数重复创建、减少子组件不必要的重新渲染,间接优化性能。它与 React.memo 配合使用时,能更有效地防止子组件因父组件函数实例变化而触发渲染。以下是具体分析:
1. useCallback 的核心作用记忆化函数:useCallback 会缓存函数实例,仅在依赖项变化时重新创建函数。例如:
const onDeleteRow = useCallback((id) => { setRows(prevRows => prevRows.filter(row => row.id !== id));}, []); // 依赖项为空数组,函数仅创建一次若未使用 useCallback,父组件每次渲染都会生成新的 onDeleteRow 函数实例,即使其逻辑未变。
避免子组件不必要的渲染:当父组件将函数作为 prop 传递给子组件时,若函数实例每次变化,即使子组件被 React.memo 包裹,也会因 prop 变化触发重新渲染。useCallback 可固定函数实例,减少此类渲染。
在提供的代码中,RowComponent 是父组件,Item 是子组件:
父组件优化:
addRow 和 onDeleteRow 通过 useCallback 缓存,避免每次渲染生成新函数。
memoizedItemRender 使用 useMemo 缓存 children 渲染结果(但此处直接返回 children 可能无实际优化效果,需根据场景调整)。
子组件优化:
Item 被 React.memo 包裹,且自定义比较逻辑仅检查 row.id。若父组件传递的 onDeleteRow 函数实例固定(因 useCallback),且 row.id 未变,则 Item 不会重新渲染。
子组件渲染成本高。
父组件频繁渲染且向子组件传递函数作为 props。
useCallback 的核心目的是通过记忆化函数实例,减少子组件不必要的重新渲染,从而间接优化性能。它与 React.memo 配合使用时,能更精准地控制组件渲染行为,但需合理管理依赖项并避免过度优化。