🎙 欢迎来到《前端达人 · 播客书单》第 16 期。
今天我们来聊聊两个非常实用但经常被误解的 React Hook:useRef
和 useMemo
。
你可能在项目里“见过但没用过”,或者“不太确定场景”,这节课我们用简单示例和对比讲清楚:
useState
有啥不同?自 React 16.8 起,Hook 正式成为函数组件的第一公民,赋予它们类似类组件的能力:状态、生命周期、副作用……
Hook 的使用有两个前提记住:
🚫 不能写在 if / for / 内层函数中
✅ 只能写在函数组件的“顶层作用域”
useRef
是用来存储“不会引起渲染”的可变值容器。
const countRef = useRef(0);
console.log(countRef.current); // 访问值
countRef.current = 100; // 修改值,不会触发组件更新
🧠 小知识点:
useState
不一样,它不会触发渲染.current
才是真正存放的值你可能已经遇到这个场景:
页面加载后自动聚焦一个 input 输入框,怎么办?
👀 用 useRef
+ useEffect
就搞定:
function MyComponent() {
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
inputRef.current?.focus(); // 聚焦 input
}, []);
return <input ref={inputRef} />;
}
除此之外,还可以保存:
在 TS 中使用 useRef
时,强烈推荐加类型标注!
const inputRef = useRef<HTMLInputElement>(null);
const buttonRef = useRef<HTMLButtonElement>(null);
📌 如果初始值非 null,比如数字:
const countRef = useRef(0); // 自动推断为 number 类型
🎁 实用小表:
DOM 元素类型 | 对应 TS 类型 |
---|---|
input | HTMLInputElement |
button | HTMLButtonElement |
div | HTMLDivElement |
useMemo
用来做一件事:缓存复杂计算的结果。
const memoizedValue = useMemo(() => {
return expensiveCalculation(a, b);
}, [a, b]);
⚙️ 它接受两个参数:
1️⃣ 一个返回值的函数 2️⃣ 一个依赖项数组(变化才会重新执行函数)
📌 如果依赖项不变,它就会“拿缓存值”,而不是重新计算。
✅ 优点:
React.memo
配合,减少子组件重渲染⚠️ 使用注意:
不要滥用 useMemo 的几种情况 |
---|
简单的计算,没必要缓存 |
每次都变化的依赖项,等于没缓存 |
想“预优化”而不是“真实遇到性能问题” |
📌 小贴士:先量化,再优化。性能瓶颈是真实的,才需要 useMemo。
来个表格对比最直观👇
特性 | useRef | useMemo |
---|---|---|
功能 | 存储值 / 获取 DOM 引用 | 缓存复杂计算结果 |
是否触发渲染 | ❌ 不会触发 | ❌ 自身不触发,仅在依赖变动时重新计算 |
常见用途 | input 聚焦、定时器 ID、外部状态 | 大数组计算、过滤、排序等性能敏感操作 |
👨💻 练习 1:
用 useRef
实现一个自动聚焦的登录框
👨💻 练习 2:
用 useMemo
模拟一个耗时计算(比如 10000 项数据过滤)
🔍 bonus:
用 Chrome DevTools 看组件是否重新渲染,对比 useMemo
使用前后性能差异
#React #React播客 #前端播客 #前端达人 #TypeScript