What Is React “useRef” Hook And How To Use?

React, a popular JavaScript library for building user interfaces, comes equipped with a variety of hooks that empower developers to manage state, side effects, and the lifecycle of functional components. One such powerful hook is “useRef”.

In this article, we’ll delve into the intricacies of the React useRef hook, exploring its use cases, syntax, and benefits.

What is useRef Hook?

useRef is a hook in React that provides a way to interact with the DOM (Document Object Model) directly.

Unlike useState, which is commonly used to manage the state of a component, useRef is primarily used for accessing and interacting with DOM elements.

It creates a mutable object called a ref object, which can be attached to React elements to reference and persistently hold a value across renders.

Basic Syntax of useRef

To create a useRef reference, you simply call the useRef function and store the result in a variable. For example:

import { useRef, useEffect } from 'react';

function MyComponent() {
    // Creating a ref object
    const myRef = useRef(initialValue);

    // Using the ref in the component
    useEffect(() => {
        // Accessing the current property of the ref object
        console.log(myRef.current);
    }, []);

    return <div ref={myRef}>Hello, useRef!</div>;
}

Use Cases of useRef

1. Accessing and Managing DOM Elements

One of the primary use cases of useRef is to gain direct access to DOM elements.

By attaching a ref to a React element, developers can interact with and manipulate the underlying DOM node.

import { useRef, useEffect } from 'react';

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

    useEffect(() => {
        // Automatically focuses on the input element when the component mounts
        inputRef.current.focus();
    }, []);

    return <input ref={inputRef} />;
}

2. Preserving Values Across Renders

Unlike state variables, the value of a ref persists across renders without triggering a re-render.

This characteristic makes useRef suitable for storing mutable values that do not affect the component’s rendering.

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

function Counter() {
    const count = useRef(0); // Initial count value

    useEffect(() => {
        // Log the count value without triggering a re-render
        console.log(count.current);
    }, []);

    return (
        <button
            onClick={() => {
                count.current += 1; // Update the count value
            }}
        >
            Increment
        </button>
    );
}

3. Storing Previous Values

You can use useRef to hold the previous value of a state or prop. This is helpful when you want to compare the current value with the previous value to perform specific actions.

function MyComponent({ value }) {
    const prevValue = useRef();

    useEffect(() => {
        if (value !== prevValue.current) {
            console.log('Value changed from', prevValue.current, 'to', value);
            prevValue.current = value;
        }
    }, [value]);

    return <div>{value}</div>;
}

Caveats and Best Practices

While useRef is a powerful tool, there are some important considerations and best practices to keep in mind:

1. Avoid Using useRef for Component State

useRef is not designed to trigger re-renders like useState. It should not be used as a replacement for state variables when the goal is to update the UI.

2. Use Refs for Uncontrolled Components

When working with uncontrolled components or when direct manipulation of the DOM is necessary, useRef is an appropriate choice. However, for most controlled components, state management is preferred.

3. Accessing Child Component Methods

useRef can be used to access methods or properties of child components. This can be handy when you need to interact with a child component imperatively.

import { useRef, useEffect } from 'react';

function ParentComponent() {
    const childRef = useRef();

    useEffect(() => {
        // Accessing a method of the child component
        childRef.current.doSomething();
    }, []);

    return <ChildComponent ref={childRef} />;
}

const ChildComponent = React.forwardRef((props, ref) => {
    // Component logic...

    // Exposing a method to the parent component using forwardRef
    useImperativeHandle(ref, () => ({
        doSomething: () => {
            // Implementation...
        },
    }));

    return <div>ChildComponent</div>;
});

Conclusion

In conclusion, the React useRef hook is a versatile tool that allows developers to interact with the DOM directly and manage mutable values across renders.

Understanding its use cases and best practices is essential for leveraging its full potential in building efficient and maintainable React applications.

By incorporating useRef into your React toolkit, you can enhance your ability to work with the DOM and manage component state more effectively.