techStackGuru

React useRef Hook


Using useRef, you can create mutable references to values that persist across component renders. DOM elements and values can be accessed and modified without re-rendering the component.

A mutable ref object is returned by the useRef hook, which has the property .current. Any value may be stored in this property, including DOM elements, objects, and primitive values. Components are not rerendered when the .current value changes.

A React useRef example:

import React, { useRef } from 'react';

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

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

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

This example uses useRef(null) to create a ref named inputRef. Input elements are attached to refs using ref attributes. InputRef.current is then focused by the .focus() method when the handleClick function is called on the inputRef.current.

Besides DOM elements, useRef can store and access other values. In addition to storing previous values, you can also maintain a reference to setInterval and setTimeout IDs, and keep any other mutable value you want to persist without re-rendering.

Maintaining Previous Values:

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

function ExampleComponent() {
  const previousValueRef = useRef('');

  useEffect(() => {
    previousValueRef.current = 'New Value';
  }, []);

  return (
    <div>
      <p>Previous Value: {previousValueRef.current}</p>
      <p>New Value: New Value</p>
    </div>
  );
} 

Here, useRef is used to keep track of a components previous value. A previousValueRef.current is updated within the useEffect hook, and it will persist across renders.

Preserving Values in Callbacks:

import React, { useRef } from 'react';

function ExampleComponent() {
  const counterRef = useRef(0);

  const handleClick = () => {
    counterRef.current += 1;
    console.log(counterRef.current);
  };

  return (
    <div>
      <button onClick={handleClick}>Increment</button>
    </div>
  );
} 

The useRef parameter is used in this example to maintain the value of a counter when the handleClick function is called multiple times. Each time the button is clicked, the counterRef.current value will persist and increment.

Storing and Accessing API Responses:

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

function ExampleComponent() {
  const apiResponseRef = useRef(null);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => {
        apiResponseRef.current = data;
        console.log(apiResponseRef.current);
      });
  }, []);

  return <div>Data Loading...</div>;
} 

As an example, we are using useRef to store the response of an API call. In the component, apiResponseRef.current is updated when the response is received, so it can be accessed later.

Controlling Focus or Selection:

import React, { useRef } from 'react';

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

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

  const handleSelectText = () => {
    inputRef.current.select();
  };

  return (
    <div>
      <input ref={inputRef} type="text" />
      <button onClick={handleButtonClick}>Focus Input</button>
      <button onClick={handleSelectText}>Select Text</button>
    </div>
  );
} 

Here, useRef creates a reference to an input element. When a button is clicked, handleButtonClick uses inputRef.current.focus() to focus the input, while handleSelectText uses inputRef.current.select() to select the text.