[React.js] - Part 12. React Hooks - useRef Hook

Ace Lennox
19 Jan 20253 minutes to read

The useRef Hook in React is a versatile tool that allows developers to persist values between renders, access DOM elements directly, and store mutable values without triggering re-renders. In this guide, we'll explore how to use useRef effectively with creative and dynamic examples.


What is useRef?

The useRef Hook provides a way to manage persistent values across renders. Unlike useState, updating a useRef value does not cause the component to re-render. It also allows you to interact directly with DOM elements, bypassing React's abstraction when necessary.


Key Features of useRef

  1. Does Not Trigger Re-Renders: You can store values that change without affecting the render cycle.

  2. Access DOM Elements Directly: Use useRef to manipulate DOM elements when required.

  3. Persist Previous State: Keep track of previous state values across renders.


Examples to Illustrate useRef

Example 1: Tracking Render Count

Let’s count how many times a component renders, but without causing an infinite loop:

import { useState, useEffect, useRef } from "react";  
import ReactDOM from "react-dom/client";  

function RenderCounter() {  
  const [text, setText] = useState("");  
  const renderCount = useRef(0);  

  useEffect(() => {  
    renderCount.current += 1;  
  });  

  return (  
    <>  
      <input  
        type="text"  
        value={text}  
        onChange={(e) => setText(e.target.value)}  
      />  
      <h2>This component has rendered {renderCount.current} times!</h2>  
    </>  
  );  
}  

const root = ReactDOM.createRoot(document.getElementById("root"));  
root.render(<RenderCounter />);  

Here, useRef tracks the render count without causing additional re-renders. Try typing into the input field to see the count increase dynamically.


Example 2: Focusing an Input Field

Using useRef, you can directly focus an input field when a button is clicked:

import { useRef } from "react";  
import ReactDOM from "react-dom/client";  

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

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

  return (  
    <>  
      <input type="text" ref={inputRef} placeholder="Click the button to focus me" />  
      <button onClick={handleFocus}>Focus Input</button>  
    </>  
  );  
}  

const root = ReactDOM.createRoot(document.getElementById("root"));  
root.render(<InputFocus />);  

This example demonstrates how useRef can be used for DOM manipulation while maintaining React's declarative nature.


Example 3: Remembering Previous Values

Use useRef to remember the previous value of a state:

import { useState, useEffect, useRef } from "react";  
import ReactDOM from "react-dom/client";  

function RememberPrevious() {  
  const [current, setCurrent] = useState("");  
  const previous = useRef("");  

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

  return (  
    <>  
      <input  
        type="text"  
        value={current}  
        onChange={(e) => setCurrent(e.target.value)}  
      />  
      <h2>Current Value: {current}</h2>  
      <h2>Previous Value: {previous.current}</h2>  
    </>  
  );  
}  

const root = ReactDOM.createRoot(document.getElementById("root"));  
root.render(<RememberPrevious />);  

By combining useState, useEffect, and useRef, this example shows how to track the previous value of a state without unnecessary re-renders.


Example 4: Measuring Element Dimensions

Here’s an example of using useRef to measure the dimensions of an element:

import { useEffect, useRef, useState } from "react";  
import ReactDOM from "react-dom/client";  

function MeasureBox() {  
  const boxRef = useRef();  
  const [dimensions, setDimensions] = useState({ width: 0, height: 0 });  

  useEffect(() => {  
    const { offsetWidth, offsetHeight } = boxRef.current;  
    setDimensions({ width: offsetWidth, height: offsetHeight });  
  }, []);  

  return (  
    <>  
      <div  
        ref={boxRef}  
        style={{ width: "200px", height: "100px", background: "lightblue" }}  
      ></div>  
      <h2>Width: {dimensions.width}px</h2>  
      <h2>Height: {dimensions.height}px</h2>  
    </>  
  );  
}  

const root = ReactDOM.createRoot(document.getElementById("root"));  
root.render(<MeasureBox />);  

This example illustrates how useRef can interact with DOM elements to retrieve information like dimensions.


Best Practices for Using useRef

  1. Use it Sparingly: Rely on React's state and props for most use cases. Reserve useRef for special cases like DOM manipulation or persisting values.

  2. Avoid Replacing State: If a value requires re-rendering the UI, use useState instead of useRef.

  3. Always Check .current: Ensure the current property is available before accessing it.


Conclusion

The useRef Hook is a powerful addition to React's toolbox, offering flexibility for managing persistent values, interacting with the DOM, and remembering previous states. By understanding and experimenting with the examples above, you can unlock its full potential and add a new layer of interactivity to your React applications.

Start incorporating useRef into your projects today and see how it simplifies your workflow!


Source Code

The complete source code for this part is available on GitHub


Recent Posts

Latest Posts


logo

Explore insightful articles and tutorials on programming, web development, and mobile app creation. Dive into topics like ReactJS, Next.js, Android, iOS, and modern coding practices. Learn with practical examples and tips for building robust, responsive, and high-performing applications. Perfect for developers of all levels seeking to enhance their skills.

Social

© 2025. All rights reserved