REACT useRef

The useRef hook in React is used to directly reference DOM elements or persist mutable values without causing re-renders. It is an incredibly useful tool for scenarios where you need to interact with the DOM or retain a mutable state across renders.

When to Use useRef

  1. Accessing DOM Elements: Directly manipulate or access a DOM element (e.g., focusing an input, scrolling).
  2. Storing Mutable Data: Retain values (like timers, IDs, or previous states) without triggering re-renders.
  3. Keeping Previous Values: Store the previous value of props or state for comparison.

Syntax

const refContainer = useRef(initialValue);

Try It Now

  • refContainer: An object with a current property where the value is stored.
  • initialValue: The initial value to be assigned to the current property.

 

Example 1: Accessing a DOM Element

Code Example: Focus on an Input Field

import React, { useRef } from "react";

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

    const handleFocus = () => {
        inputRef.current.focus(); // Focus the input field
    };

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

export default FocusInput;

Try It Now

  • Explanation:
    • useRef creates a reference to the input element.
    • The current property of the reference is used to call the focus method.

 

Example 2: Persisting Mutable Values

Code Example: Store Timer Value

import React, { useRef, useState } from "react";

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

    const startTimer = () => {
        if (!timerRef.current) {
            timerRef.current = setInterval(() => {
                setSeconds((prev) => prev + 1);
            }, 1000);
        }
    };

    const stopTimer = () => {
        clearInterval(timerRef.current);
        timerRef.current = null;
    };

    return (
        <div>
            <p>Timer: {seconds} seconds</p>
            <button onClick={startTimer}>Start</button>
            <button onClick={stopTimer}>Stop</button>
        </div>
    );
}

export default Timer;

Try It Now

  • Explanation:
    • timerRef holds the timer ID.
    • Since useRef doesn’t trigger re-renders, the timer logic remains efficient.

Example 3: Storing Previous State

Code Example: Previous Value Comparison

import React, { useRef, useEffect, useState } from "react";

function PreviousValueExample() {
    const [count, setCount] = useState(0);
    const prevCount = useRef(null);

    useEffect(() => {
        prevCount.current = count; // Update the previous value
    });

    return (
        <div>
            <p>Current Count: {count}</p>
            <p>Previous Count: {prevCount.current}</p>
            <button onClick={() => setCount((prev) => prev + 1)}>Increment</button>
        </div>
    );
}

export default PreviousValueExample;

Try It Now

  • Explanation:
    • The prevCount ref stores the count value from the previous render.
    • It doesn’t cause a re-render when updated.

Example 4: Managing Animations

Code Example: Smooth Scrolling

import React, { useRef } from "react";

function SmoothScroll() {
    const divRef = useRef(null);

    const scrollToBottom = () => {
        divRef.current.scrollIntoView({ behavior: "smooth" });
    };

    return (
        <div>
            <div style={{ height: "500px", overflow: "auto", border: "1px solid black" }}>
                <div style={{ height: "1000px" }}>Scroll Down</div>
                <div ref={divRef}>You’ve reached the bottom!</div>
            </div>
            <button onClick={scrollToBottom}>Scroll to Bottom</button>
        </div>
    );
}

export default SmoothScroll;

Try It Now

  • Explanation:
    • useRef targets a specific DOM element.
    • The scrollIntoView method is triggered for smooth scrolling.

Key Points About useRef

  1. Does Not Trigger Re-Renders: Updating the .current property doesn’t re-render the component.
  2. Persistent Across Renders: The value persists between renders, unlike local variables inside the function.
  3. Avoid Overuse: Use useRef primarily for DOM manipulation or storing non-reactive data.

Common Mistakes with useRef

  1. Misusing for State: Don’t use useRef for values that need to trigger re-renders. Use useState instead.
  2. Unnecessary Updates: Avoid frequent updates to current when it isn’t necessary.
  3. Improper Initial Value: Ensure the initialValue matches the type of data you plan to store.

Best Practices

  • Use useRef for accessing or modifying DOM elements directly.
  • Combine with useEffect for side effects that involve the DOM.
  • For better readability, encapsulate logic involving useRef in custom hooks when reused frequently.

 

useRef is a lightweight and powerful tool for managing mutable references, making it invaluable for specific scenarios in React development.