Files
kunstenkamp/.agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md
2026-02-24 11:35:17 +01:00

1.7 KiB

title, impact, impactDescription, tags
title impact impactDescription tags
Use useRef for Transient Values MEDIUM avoids unnecessary re-renders on frequent updates rerender, useref, state, performance

Use useRef for Transient Values

When 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.

Incorrect (renders every update):

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",
      }}
    />
  );
}

Correct (no re-render for tracking):

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)",
      }}
    />
  );
}