Delving Developer

Mastering useRef in React: A Comprehensive Guide

Eddie Cunningham
Eddie Cunningham
4 min readReact.js
Cover Image for Mastering useRef in React: A Comprehensive Guide

React is known for its declarative nature and making it easy to manage component state. However, sometimes it becomes necessary to interact with DOM elements or work with mutable values that do not trigger a re-render. That's where the useRef hook comes in handy. In this article, we will learn how to master the useRef hook in React for various use cases, from managing form elements and hooks to focus management and DOM manipulation.

What is useRef?link

Before diving into specifics, let's understand what useRef is. The useRef hook is part of the React library, which allows functional components to access mutable values during the component lifecycle without triggering a re-render. While useState provides a way to manage state in functional components, useRef provides a way to interact with mutable values that persist across re-renders.

The useRef hook returns a mutable object, which holds the .current property initialized with the passed argument, and it does not change during the component's lifecycle.

Here's a simple syntax:

const refName = useRef(initialValue);

Now that we understand the basics, let's dive into some use cases.

Use Case 1: Form Elements and Hookslink

In this use case, we will use useRef to manage form elements and hooks. For example, consider a simple form with an input field and a button. In a class-based component, we would use a ref to access the input value, while with hooks, we can use the useState to manage the input state. However, using useState with larger forms can get unwieldy. That's when useRef comes to the rescue.

import React, { useRef } from 'react';

function TextInput() {
  const inputRef = useRef();

  const handleSubmit = () => {
    console.log(inputRef.current.value);
  };

  return (
    <>
      <input ref={inputRef} type="text" />
      <button onClick={handleSubmit}>Submit</button>
    </>
  );
}

export default TextInput;

Use Case 2: Focus Managementlink

Handling focus in forms is one of the most common use cases for refs. We can use useRef to direct the user's attention to a specific input when a form loads or if there's an error.

import React, { useRef, useEffect } from 'react';

function TextInputWithFocus() {
  const inputRef = useRef();

  useEffect(() => {
    inputRef.current.focus();
  }, []);

  return (
    <>
      <input ref={inputRef} type="text" />
    </>
  );
}

export default TextInputWithFocus;

Use Case 3: DOM Manipulationlink

Although React encourages us to avoid direct DOM manipulation, there are some scenarios where it becomes necessary. For instance, we may need to work with third-party libraries or implement complex animations. In such cases, useRef helps by providing access to DOM elements.

import React, { useRef, useEffect } from 'react';

function DOMManipulation() {
  const divRef = useRef();

  useEffect(() => {
    const divElement = divRef.current;
    divElement.style.backgroundColor = 'blue';
  }, []);

  return (
    <>
      <div ref={divRef}>This div will have a blue background</div>
    </>
  );
}

export default DOMManipulation;

Use Case 4: Persisting Values Across Rerenderslink

useRef is highly useful when you want to persist a value across multiple rerenders without triggering a re-render.

import React, { useState, useRef } from 'react';

function CountRenders() {
  const [count, setCount] = useState(0);
  const renderCount = useRef(0);

  renderCount.current = renderCount.current + 1;

  return (
    <>
      <p>{`Rendered ${renderCount.current} times.`}</p>
      <button onClick={() => setCount(count + 1)}>{`Count: ${count}`}</button>
    </>
  );
}

export default CountRenders;

In this example, each time the button is clicked incrementing the count state, the render count will also increment, but the component will not re-render due to the renderCount.

Use Case 5: Timer and Interval Managementlink

Another common use case for useRef is managing timers or intervals in a functional component. useRef helps manage the timer or interval identifier without triggering a re-render.

import React, { useState, useEffect, useRef } from 'react';

function TimerComponent() {
  const [timer, setTimer] = useState(0);
  const intervalIdRef = useRef(null);

  useEffect(() => {
    intervalIdRef.current = setInterval(() => {
      setTimer((prevTimer) => prevTimer + 1);
    }, 1000);

    return () => {
      clearInterval(intervalIdRef.current);
    };
  }, []);

  return <><p>Timer: {timer} seconds.</p></>;
}

export default TimerComponent;

In the example above, we store the interval identifier in a ref, and we use useEffect when the component is mounted, setting the intervalIdRef.current to null by default. This will protect against unnecessary re-renders due to the interval identifier changes.

Recaplink

In this comprehensive guide, we have covered various use cases for useRef in React:

  1. Managing Form Elements and Hooks
  2. Focus Management
  3. DOM Manipulation
  4. Persisting Values Across Rerenders
  5. Timer and Interval Management

As we've seen, useRef provides a powerful way to handle mutable values that need to persist across re-renders without triggering unnecessary updates. It's an essential tool for managing form elements and hooks, focus management, and DOM manipulation. By mastering the various use cases, you can improve your React components and the user experience on your website.