React LogouseRef and References in React

In React, `useRef` is a built-in Hook that allows you to create a mutable ref object whose `.current` property can hold any mutable value. It's primarily used for two main purposes:

1. Accessing the DOM Directly: The most common use case is to get a direct reference to a DOM element (like an input field, a div, or a button) or a React component instance. This allows you to interact with the underlying DOM API directly, for example, to focus an input, trigger media playback, or measure element dimensions. When `useRef` is attached to a JSX element via the `ref` prop, its `.current` property will point to the actual DOM node after the component mounts.

2. Storing Mutable Values That Don't Trigger Re-renders: Unlike `useState`, changing the `.current` value of a ref does not trigger a re-render of the component. This makes `useRef` ideal for storing values that need to persist across renders but whose changes shouldn't cause the UI to update. Examples include timers (e.g., `setInterval` IDs), previous values of props/state, or any value that acts as an instance variable for the component.

How it works:

* `useRef` returns an object like `{ current: initialValue }`.
* When the component re-renders, `useRef` always returns the *same* ref object. This ensures that the reference remains stable across the component's lifecycle.
* You initialize it with `const myRef = useRef(initialValue);`. If you're using it to reference a DOM element, `initialValue` is often `null`.

When to use `useRef` vs. `useState`:

* Use `useState` when you need a value to be part of the component's state, and changes to it should re-render the component to reflect those changes in the UI.
* Use `useRef` when you need to store a mutable value that persists across renders but whose changes should not trigger a re-render, or when you need to directly interact with a DOM element.

Example Code

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

function RefExample() {
  // 1. Using useRef to access a DOM element
  const inputRef = useRef(null);

  // 2. Using useRef to store a mutable value that doesn't trigger re-renders
  const timerIdRef = useRef(null);
  const nonReRenderingCounter = useRef(0);

  // For comparison: A state variable that DOES trigger re-renders
  const [stateCounter, setStateCounter] = useState(0);

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

    // Start a timer using useRef to store the interval ID
    timerIdRef.current = setInterval(() => {
      console.log('Timer running...');
      nonReRenderingCounter.current += 1; // Increment ref counter, no re-render
      // To show the ref counter value in UI, you'd need a state update or effect
    }, 1000);

    // Cleanup function: Clear the interval when the component unmounts
    return () => {
      if (timerIdRef.current) {
        clearInterval(timerIdRef.current);
      }
    };
  }, []); // Empty dependency array means this effect runs once on mount

  const handleFocusClick = () => {
    // Directly manipulate the DOM element via its ref
    if (inputRef.current) {
      inputRef.current.focus();
      inputRef.current.value = 'Focused!';
    }
  };

  const handleIncrementStateCounter = () => {
    setStateCounter(prev => prev + 1);
  };

  const handleLogRefCounter = () => {
    // This will log the current value of the ref counter
    // but won't trigger a re-render of the component itself.
    alert(`Non-rendering counter (via ref): ${nonReRenderingCounter.current}`);
  };

  return (
    <div>
      <h2>useRef Examples</h2>

      {/* Example 1: Accessing DOM elements */}
      <h3>1. DOM Manipulation with Ref</h3>
      <input type="text" ref={inputRef} placeholder="I will be focused on load" style={{ padding: '8px', marginRight: '10px' }} />
      <button onClick={handleFocusClick} style={{ padding: '8px 15px' }}>Focus Input</button>
      <p>Clicking 'Focus Input' will focus the input and change its value directly.</p>

      <hr style={{ margin: '20px 0' }} />

      {/* Example 2: Storing mutable values without re-render */}
      <h3>2. Storing Mutable Values (No Re-render)</h3>
      <p>State Counter (Renders UI on change): <strong>{stateCounter}</strong></p>
      <button onClick={handleIncrementStateCounter} style={{ padding: '8px 15px', marginRight: '10px' }}>
        Increment State Counter
      </button>
      <p>Clicking this button updates `stateCounter` via `useState`, triggering a UI re-render.</p>

      <br />

      <p>Non-Rendering Counter (Ref value, doesn't re-render UI directly): This value updates in the background every second via `useEffect` but isn't shown here because it doesn't trigger re-renders directly.</p>
      <button onClick={handleLogRefCounter} style={{ padding: '8px 15px' }}>
        Log Ref Counter Value
      </button>
      <p>Clicking 'Log Ref Counter Value' will show its current value in an alert, but the component itself won't re-render just because this value changed.</p>
      <p style={{ marginTop: '10px', fontSize: '0.9em', color: '#555' }}>
        <em>Check your browser's console to see the 'Timer running...' messages from `useEffect` and how `nonReRenderingCounter.current` is incrementing.</em>
      </p>
    </div>
  );
}

export default RefExample;
```