liveBook · Manning

useRef

As explained in React Hooks in Action: With Suspense and Concurrent Mode

useRef is a React Hook that returns a persistent mutable reference object whose current value can hold a DOM element or other value without causing re-rendering when changed.

useRef returns a persistent object with a current property. React returns the same ref object across renders, while assigning a new current value does not trigger a re-render. section 5.1 section 5.1.2

Use a ref when a component needs to retain a value without displaying every change immediately:

  • Store mechanics such as setTimeout or setInterval IDs, then cancel the timer through ref.current. section 5.0 section 5.2
  • Keep a mutable value across renders by assigning to ref.current; subsequent component runs can read the updated value. section 5.1.2
  • Attach a ref to a JSX element so React places the DOM element in current, allowing direct access to properties and methods. section 5.3 section 5.3.1

Comparing state and refs

A counter using useState updates the interface when its updater runs. A counter using useRef can increment ref.current without changing the displayed value. When another state update finally re-renders the component, the interface reads and displays the ref's latest value. This difference makes refs suitable for values that support application mechanics rather than immediate UI output. section 5.1.1

Managing timers and focus

Presentation Mode stores the ID returned by setInterval in timerRef.current and clears it when the user stops the mode or leaves the page. A separate BookablesList ref attaches to the Next button; after a bookable changes, nextButtonRef.current.focus() restores the intended keyboard focus. section 5.2 section 5.3.1

Listing 5.3 Using a ref to set focus
import {useReducer, useEffect, useRef, Fragment} from "react";
import {sessions, days} from "../../static.json";
import {FaArrowRight} from "react-icons/fa";
import Spinner from "../UI/Spinner";
import reducer from "./reducer";
import getData from "../../utils/api";
 
const initialState = { /* unchanged */ };
 
export default function BookablesList () {
  // unchanged variable setup
  const nextButtonRef = useRef();            #1
 
  useEffect(() => { /* load data */ }, []);
 
  // remove timer effect and stopPresentation function
 
  function changeGroup (e) { */ unchanged */ }
 
  function changeBookable (selectedIndex) {
    dispatch({
      type: "SET_BOOKABLE",
      payload: selectedIndex
    });
    nextButtonRef.current.focus();           #2
  }
 
  function nextBookable () { /* unchanged */ }
  function toggleDetails () { /* unchanged */}
 
  if (error) {
    return <p>{error.message}</p>
  }
 
  if (isLoading) {
    return <p><Spinner/> Loading bookables...</p>
  }
 
  return (
    <Fragment>
      <div>
        <select value={group} onChange={changeGroup}>
          {groups.map(g => <option value={g} key={g}>{g}</option>)}
        </select>
        <ul className="bookables items-list-nav">
          { /* unchanged */ }
        </ul>
        <p>
          <button
            className="btn"
            onClick={nextBookable}
            ref={nextButtonRef}            #3
            autoFocus
          >
            <FaArrowRight/>
            <span>Next</span>
          </button>
        </p>
      </div>
 
      {bookable && (
        <div className="bookable-details">
          { /* Stop button removed */ }
        </div>
      )}
    </Fragment>
  );
}
#1 Call useRef and assign the ref to the nextButtonRef variable.
#2 Use the ref to focus the Next button.
#3 Assign nextButtonRef to the ref attribute in JSX.

Browse the focused BookablesList implementation, including ref creation, JSX attachment, and the focus call. section 5.3.1

How React Hooks in Action: With Suspense and Concurrent Mode covers it

How deep it goes
Explains the current property, render persistence, state comparison, timers, DOM access, focus, and uncontrolled inputs.
Examples
Uses counters, timer IDs, Presentation Mode, button focus, and an uncontrolled WeekPicker text box.
What it assumes
Assumes React components, JSX, event handlers, state updates, and effects while distinguishing refs from state.
What you can do after
Apply it to persist mutable values, cancel timers, focus elements, and read uncontrolled DOM inputs.
How it connects
Ties refs to useState, useReducer, useEffect, DOM elements, controlled components, and uncontrolled components.

Also explained in

Compare how 3 books explain useRef →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of React Hooks in Action: With Suspense and Concurrent Mode. The section links point to the parts of the book it draws on.