Article image React Hooks: An Introduction: useRef Hook: Accessing DOM Elements and Persisting Values

14.6. React Hooks: An Introduction: useRef Hook: Accessing DOM Elements and Persisting Values

Page 50 | Listen in audio

In the world of React, hooks have revolutionized how developers build components by allowing them to use state and other React features without writing a class. Among the many hooks that React offers, useRef stands out as a versatile tool for accessing DOM elements and persisting values across renders. This hook is particularly useful when you need to interact with the DOM directly or when you want to maintain mutable values that don't trigger re-renders.

The useRef hook is a part of the React Hooks API and can be imported from React in the following way:

import React, { useRef } from 'react';

The primary purpose of the useRef hook is to return a mutable object, which holds a .current property. This property can be used to store a reference to a DOM element or any other mutable value that needs to persist across renders.

Accessing DOM Elements

One of the most common use cases for useRef is to access and interact with DOM elements directly. This is particularly useful when you need to perform operations such as focusing an input field, playing or pausing a video, or measuring the dimensions of an element. Let's explore an example where we use useRef to focus an input field when a button is clicked:

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

  const handleFocus = () => {
    if (inputRef.current) {
      inputRef.current.focus();
    }
  };

  return (
    <div>
      <input ref={inputRef} type="text" />
      <button onClick={handleFocus}>Focus the input</button>
    </div>
  );
}

In this example, we create a useRef hook called inputRef and assign it to the ref attribute of the input element. The handleFocus function uses the current property of inputRef to call the focus method on the input element, bringing it into focus when the button is clicked.

Persisting Values Across Renders

Another powerful feature of the useRef hook is its ability to persist values across renders without causing re-renders. This makes it an ideal choice for storing mutable values that need to be maintained between renders but do not affect the UI. A common scenario where this is useful is when implementing timers or intervals.

Consider the following example where we use useRef to create a simple timer:

function Timer() {
  const [seconds, setSeconds] = useState(0);
  const timerRef = useRef();

  useEffect(() => {
    timerRef.current = setInterval(() => {
      setSeconds((prevSeconds) => prevSeconds + 1);
    }, 1000);

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

  return <div>Elapsed Time: {seconds} seconds</div>;
}

In this example, we use useRef to store a reference to the interval ID returned by setInterval. This allows us to clear the interval when the component is unmounted by calling clearInterval with timerRef.current. The useRef hook ensures that the interval ID persists across renders without triggering additional renders.

Comparing useRef with useState

At first glance, useRef and useState might seem similar because they both allow you to maintain values across renders. However, there are key differences between the two:

  • Reactivity: useState is reactive, meaning that whenever the state changes, the component re-renders. In contrast, useRef is not reactive, so changing the .current property does not trigger a re-render.
  • Usage: Use useState when you need to trigger a re-render upon value changes. Use useRef when you need to persist values without causing re-renders, such as when storing references to DOM elements or maintaining mutable values like timers.

Practical Use Cases for useRef

Beyond the basic examples, useRef can be applied in various practical scenarios:

1. Storing Previous Values

Sometimes, you might need to track the previous value of a state or prop. useRef can help you achieve this by storing the value across renders:

function PreviousValue({ value }) {
  const prevValueRef = useRef();

  useEffect(() => {
    prevValueRef.current = value;
  }, [value]);

  return <div>Previous Value: {prevValueRef.current}</div>;
}

In this example, we use useRef to store the previous value of the value prop. The useEffect hook updates the prevValueRef.current with the current value whenever the value prop changes.

2. Managing Form Inputs

When dealing with form inputs, useRef can be used to manage uncontrolled components, allowing you to read input values without tying them to state:

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

  const handleSubmit = (event) => {
    event.preventDefault();
    alert('Input Value: ' + inputRef.current.value);
  };

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

Here, useRef is used to access the value of the input field when the form is submitted, without the need to use useState to manage the input value.

3. Integrating with Third-Party Libraries

When integrating with third-party libraries that require direct DOM manipulation, useRef can be invaluable. For example, when using a charting library that requires a DOM element to render a chart, you can use useRef to provide the necessary reference:

function ChartComponent() {
  const chartRef = useRef();

  useEffect(() => {
    const chart = new ChartLibrary(chartRef.current, { /* chart options */ });
    return () => chart.destroy();
  }, []);

  return <div ref={chartRef}></div>;
}

In this scenario, useRef provides a reference to the div element where the chart is rendered, allowing the library to manipulate the DOM directly.

Conclusion

The useRef hook is a powerful tool in the React ecosystem, offering developers the ability to access DOM elements and persist values across renders without causing re-renders. Whether you're working with uncontrolled form inputs, integrating with third-party libraries, or managing timers and intervals, useRef provides a flexible solution for handling mutable values and DOM interactions. By understanding and leveraging the capabilities of useRef, you can enhance the performance and functionality of your React applications.

Now answer the exercise about the content:

What is the primary purpose of the `useRef` hook in React?

You are right! Congratulations, now go to the next page

You missed! Try again.

Article image React Hooks: An Introduction: useCallback Hook: Optimizing Function References

Next page of the Free Ebook:

51React Hooks: An Introduction: useCallback Hook: Optimizing Function References

9 minutes

Earn your Certificate for this Course for Free! by downloading the Cursa app and reading the ebook there. Available on Google Play or App Store!

Get it on Google Play Get it on App Store

+ 6.5 million
students

Free and Valid
Certificate with QR Code

48 thousand free
exercises

4.8/5 rating in
app stores

Free courses in
video, audio and text