1.7 KiB
1.7 KiB
title: Use useRef for Transient Values impact: MEDIUM impactDescription: 避免频繁更新时触发不必要的重渲染 tags: rerender, useref, state, performance
使用 useRef 存储临时值
当一个值变化频繁,且你不希望每次更新都触发重渲染时(例如鼠标追踪器、定时器、临时标记),应将其存储在 useRef 中,而非 useState。用组件状态管理 UI,用 ref 管理临时的 DOM 相关值。更新 ref 不会触发重渲染。
错误做法(每次更新都渲染):
function Tracker() {
const [lastX, setLastX] = useState(0)
useEffect(() => {
const onMove = (e: MouseEvent) => setLastX(e.clientX)
window.addEventListener('mousemove', onMove)
return () => window.removeEventListener('mousemove', onMove)
}, [])
return (
<div
style={{
position: 'fixed',
top: 0,
left: lastX,
width: 8,
height: 8,
background: 'black',
}}
/>
)
}
正确做法(追踪时不触发重渲染):
function Tracker() {
const lastXRef = useRef(0)
const dotRef = useRef<HTMLDivElement>(null)
useEffect(() => {
const onMove = (e: MouseEvent) => {
lastXRef.current = e.clientX
const node = dotRef.current
if (node) {
node.style.transform = `translateX(${e.clientX}px)`
}
}
window.addEventListener('mousemove', onMove)
return () => window.removeEventListener('mousemove', onMove)
}, [])
return (
<div
ref={dotRef}
style={{
position: 'fixed',
top: 0,
left: 0,
width: 8,
height: 8,
background: 'black',
transform: 'translateX(0px)',
}}
/>
)
}