👨🏫 本系列由前端面试真题博主 Kincy 发起,每日更新一题,通勤路上轻松掌握高频知识点。
📢 如果你想第一时间获取更新,或与群友交流面试经验、内推信息,欢迎加入微信群(文末扫码)!
🧠 系列前言:
面试题千千万,我来帮你挑重点。每天一道,通勤路上、蹲坑时、摸鱼中,技术成长不设限!本系列主打幽默 + 深度 + 面霸必备语录,你只管看,面试场上稳拿 offer!
💬 面试官发问:
“React 中
useMemo和useCallback是干嘛的?它们怎么优化性能的?什么时候该用,什么时候不该用?”
哼哼,这题是 Hooks 界的“灵魂拷问”!
答不清楚,你就是乱抹防晒霜——看起来在优化,其实是白抹。
🎯 快答区(面霸速记版)
useMemo(fn, deps)返回fn()的计算结果,用于缓存值useCallback(fn, deps)返回fn本身,用于缓存函数引用- 它俩的存在就是为了避免无意义的重新计算或重新创建函数
如果组件频繁渲染、子组件依赖 props 变化,这俩钩子就能让你“一键优化、性能暴涨”
🧪 一、为什么需要 useMemo 和 useCallback?
你写了一个简单函数组件:
function App() {
const result = heavyCalculation(data)
return <Child value={result} />
}
每次父组件更新,heavyCalculation() 就会重新执行,哪怕 data 根本没变!
于是你写:
const result = useMemo(() => heavyCalculation(data), [data])
✅ 如果
data没变,就复用上一次的计算结果
🔁 二、useCallback 和 useMemo 有啥区别?
来看这两个定义:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b])
const memoizedFn = useCallback(() => handleClick(id), [id])
简单粗暴地记:
useMemo是缓存值useCallback是缓存函数
其实这俩内部原理一样,本质上:
useCallback(fn, deps) === useMemo(() => fn, deps)
👶 三、你可能踩过这些坑...
❌ 误区 1:以为它会“自动提升性能”
const memoizedFn = useCallback(() => {
console.log('点击了')
}, [])
你这样写没有任何必要。这个函数根本不依赖任何变化,用不用 useCallback 都没啥区别。
🚨 它不会自动加速,只在“你真的在频繁重新创建函数/值”时才值得用!
❌ 误区 2:一股脑加 everywhere
const value = useMemo(() => 1 + 1, [])
你是认真的吗兄弟?1 + 1 也要缓存?
React:你用计算器能做的事,别拿我当缓存仓库啊!
📦 四、和 React.memo 配合食用,效果更佳!
你有一个子组件:
const Child = React.memo(({ onClick }) => {
console.log('子组件渲染!')
return <button onClick={onClick}>点我</button>
})
每次父组件重新渲染,如果 onClick 是新函数,React.memo 就失效,还是会更新。
这时你需要:
const handleClick = useCallback(() => {
doSomething()
}, [])
<Child onClick={handleClick} />
完美:子组件不更新,函数不变,性能稳定!
🧩 五、源码小窥探(简化版)
React 内部其实是这么判断是否需要重新执行:
if (areHookInputsEqual(prevDeps, nextDeps)) {
return previousResult
} else {
const result = computeFn()
saveResult(result)
return result
}
areHookInputsEqual 就是你熟悉的 浅比较(Object.is),所以记得依赖项不能随手创建新对象:
const obj = { a: 1 } // 每次 render 都是新对象
要想避免重新执行,要么用 useMemo 创建,要么别放对象进去。
🎓 六、装 X 语录(限时使用)
“useMemo 和 useCallback 的本质是缓存机制,目的是减少不必要的重新计算和子组件重渲染。”
“它们配合 React.memo 使用,才能发挥真正的性能优化作用。”
“盲目使用只会徒增复杂度,记住一句话:有性能问题再上 memo。”
✅ 总结一句话
useMemo/useCallback是缓存值和函数的神器,但不是优化万金油,切记“按需使用”!
🔮 明日预告
明天我们聊聊 useRef:一个让人误以为只能“引用 DOM”的钩子,其实它是 Hook 版的“仓库管理员”!🏪
📌 点赞 + 收藏 + 关注系列,Hook 的坑你一个都不会踩!
📚 本系列每天一题,持续更新中!
👉 扫码加入【前端面试题交流群】,一起成长、交流、内推、分享机会!
备注“掘金”优先通过