Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Apply 62 React and Next.js performance optimization rules from Vercel Engineering
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
rules/rerender-use-ref-transient-values.md
1---2title: Use useRef for Transient Values3impact: MEDIUM4impactDescription: avoids unnecessary re-renders on frequent updates5tags: rerender, useref, state, performance6---78## Use useRef for Transient Values910When a value changes frequently and you don't want a re-render on every update (e.g., mouse trackers, intervals, transient flags), store it in `useRef` instead of `useState`. Keep component state for UI; use refs for temporary DOM-adjacent values. Updating a ref does not trigger a re-render.1112**Incorrect (renders every update):**1314```tsx15function Tracker() {16const [lastX, setLastX] = useState(0)1718useEffect(() => {19const onMove = (e: MouseEvent) => setLastX(e.clientX)20window.addEventListener('mousemove', onMove)21return () => window.removeEventListener('mousemove', onMove)22}, [])2324return (25<div26style={{27position: 'fixed',28top: 0,29left: lastX,30width: 8,31height: 8,32background: 'black',33}}34/>35)36}37```3839**Correct (no re-render for tracking):**4041```tsx42function Tracker() {43const lastXRef = useRef(0)44const dotRef = useRef<HTMLDivElement>(null)4546useEffect(() => {47const onMove = (e: MouseEvent) => {48lastXRef.current = e.clientX49const node = dotRef.current50if (node) {51node.style.transform = `translateX(${e.clientX}px)`52}53}54window.addEventListener('mousemove', onMove)55return () => window.removeEventListener('mousemove', onMove)56}, [])5758return (59<div60ref={dotRef}61style={{62position: 'fixed',63top: 0,64left: 0,65width: 8,66height: 8,67background: 'black',68transform: 'translateX(0px)',69}}70/>71)72}73```74