DevPath · Learn to code ESPTEN

useEffect, useRef and effects

useRef: DOM and mutable values

What is a ref?

useRef creates an object { current: ... } that persists between renders and that you can mutate freely. The distinctive part: changing ref.current does NOT trigger a re-render. It's the opposite of useState.

const ref = useRef(initialValue);
ref.current;          // read the value
ref.current = other;  // change it (without re-rendering)

It has two main uses.

1) Referencing a DOM node

By passing a ref to the ref attribute of an element, React puts the real DOM node into ref.current. This lets you do imperative things like focusing an input:

function SearchBox() {
  const inputRef = useRef(null);

  return (
    <div>
      <input ref={inputRef} placeholder="Search…" />
      <button onClick={() => inputRef.current.focus()}>Focus</button>
    </div>
  );
}

When the component mounts, inputRef.current points to the real <input>, and we can call .focus(), .scrollIntoView(), etc.

2) Storing a mutable value that does NOT re-render

Sometimes you need to remember a piece of data between renders but you don't want changing it to re-render the interface: the id of a setInterval, the previous value of a prop, an internal counter... That goes in a ref, not in state.

function Render() {
  const renders = useRef(0);
  renders.current++;            // counts renders WITHOUT triggering another render
  return <p>Renders: {renders.current}</p>;
}

State vs. ref

useState useRef
On value change re-renders does not re-render
What for data shown in the UI DOM and "behind the scenes" values
How to change it with setX(...) mutating ref.current

Practical rule: if the data is shown and must appear updated, it goes in state. If it's an internal detail the UI doesn't need to display on change, it goes in a ref. Want to show a ref's value on screen? Copy it to state at the right moment (e.g., when pressing a button).

Put this into practice

DevPath is a hands-on course: you read the theory here; in the app you put it into practice with exercises that really run, offline.

Start free in the app →
← Fetching data with useEffectView the module →