⚛️ React Q34 / 113

What is useRef hook?

AI-Powered Answer ✓ Answered

The `useRef` hook in React provides a way to create mutable ref objects that can persist a value across re-renders without causing the component to re-render when the ref's value changes. It's primarily used for direct interaction with the DOM or to store any mutable value that doesn't need to trigger UI updates.

What is `useRef`?

The useRef hook returns a mutable ref object whose .current property is initialized to the argument passed (initialValue). The returned object will persist for the full lifetime of the component. Unlike useState, updating the .current property of a ref does not trigger a re-render of the component.

This makes useRef ideal for storing values that you want to keep track of across renders, but whose changes should not cause a re-render. It's like an instance variable for a functional component.

Common Use Cases

Accessing DOM Elements

This is perhaps the most common use case. useRef allows you to directly interact with DOM nodes or React components. When you attach a ref to an element using the ref prop, React will place the DOM element into the .current property of the ref object.

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

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

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

  return (
    <div>
      <input type="text" ref={inputRef} />
      <button onClick={() => alert(inputRef.current.value)}>Get Input Value</button>
    </div>
  );
}

Storing Mutable Values That Don't Trigger Re-renders

You can use useRef to store any value that needs to persist across renders but doesn't need to trigger a UI update when it changes. Examples include timers, interval IDs, previous state values, or any object that you want to keep a consistent reference to.

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

function CounterWithoutRender() {
  const counterRef = useRef(0);
  const [_, setRerender] = useState(false); // Dummy state to force re-render

  const increment = () => {
    counterRef.current = counterRef.current + 1;
    console.log('Counter value (no re-render):', counterRef.current);
  };

  const forceRerender = () => {
    setRerender(prev => !prev); // Toggles state to force re-render
  };

  return (
    <div>
      <p>Ref Counter Value: {counterRef.current}</p>
      <button onClick={increment}>Increment Ref Counter (No Re-render)</button>
      <button onClick={forceRerender}>Force Re-render (to see ref value updated)</button>
      <p>(Note: The paragraph above won't update until a re-render is triggered by something else)</p>
    </div>
  );
}

Referencing the Previous Value of Props or State

A common pattern is to use useRef in conjunction with useEffect to store the previous value of a prop or state variable, allowing you to compare current and previous values in subsequent renders.

Key Characteristics

  • Returns a mutable ref object whose .current property is initialized to the passed argument (initialValue).
  • The returned ref object will persist for the full lifetime of the component.
  • Updating a ref's .current value does *not* trigger a re-render of the component.
  • useRef does *not* notify you when its content changes; you typically use useEffect if you need side effects based on changes to the ref's value.

Syntax

javascript
const myRef = useRef(initialValue);

Summary

In essence, useRef is a powerful hook for storing values that need to persist across renders without causing the component to re-render upon update. It's a fundamental tool for managing direct DOM interactions and maintaining mutable, non-reactive data within functional components.