useRef, useMemo & useCallback

⚛️ ReactLesson 9Intermediate

These three hooks let you optimize performance and access DOM elements directly. useRef persists values without triggering re-renders. useMemo caches expensive computations. useCallback caches function references.

1 useRef
React — useRef
import { useRef, useEffect } from "react";

function VideoPlayer() {
  const videoRef = useRef(null);   // DOM reference

  useEffect(() => {
    videoRef.current.play(); // direct DOM access
  }, []);

  return <video ref={videoRef} src="/intro.mp4" />;
}

// useRef for mutable values (won't cause re-render)
function Timer() {
  const [running, setRunning] = useState(false);
  const intervalRef = useRef(null);

  const start = () => {
    intervalRef.current = setInterval(() => tick(), 1000);
    setRunning(true);
  };
  const stop = () => {
    clearInterval(intervalRef.current);
    setRunning(false);
  };

  return <button onClick={running ? stop : start}>{running ? "Stop" : "Start"}</button>;
}
2 useMemo & useCallback
React — useMemo & useCallback
import { useMemo, useCallback } from "react";

function DataTable({ data, filter }) {
  // useMemo — only recomputes when data or filter changes
  const filtered = useMemo(() => {
    console.log("Filtering..."); // expensive computation
    return data.filter(row => row.name.includes(filter));
  }, [data, filter]);

  // useCallback — stable function reference for child components
  const handleDelete = useCallback((id) => {
    setData(prev => prev.filter(row => row.id !== id));
  }, []); // no deps — function never needs to change

  return (
    <ul>
      {filtered.map(row => (
        <Row key={row.id} data={row} onDelete={handleDelete} />
      ))}
    </ul>
  );
}

// Wrap child with React.memo to prevent unnecessary re-renders
const Row = React.memo(({ data, onDelete }) => (
  <li>{data.name} <button onClick={() => onDelete(data.id)}>Delete</button></li>
));
3 Code Challenge
Challenge: Build a sortable table of 1000 rows. Use useMemo to sort the data only when the sort column changes. Wrap individual row components in React.memo and verify fewer re-renders using React DevTools.