useRef is a React Hook that allows you to create a mutable reference object. This reference object can hold a value that persists across renders and changing its .current value does NOT trigger a re-render. It's also commonly used to get direct access to DOM elements.
What is useRef?
useRef is a React hook returning a mutable ref object with a single .current property.
const myRef = useRef(initialValue);
// myRef looks like: { current: initialValue }- Initialization: The - initialValueyou provide is used to set- myRef.currentonly during the component's initial render. It's ignored on subsequent renders. If you omit the argument,- initialValuedefaults to- undefined.
- Return Value: - useRefreturns the same ref object on every render of a given component instance. This is how it persists across renders.
🗝️Key Characteristics:
- Mutable - .currentProperty:
 You directly modify the- ref.currentproperty (e.g.,- myRef.current = newValue), unlike state variables from- useState(which you update via a setter function),
- No Re-render on Change: 
 Assigning a new value to- ref.currentdoes not trigger a component re-render. This is the most significant difference from- useState.
- Persistence Across Renders: 
 The ref object itself (and the value stored in ref.current) persists for the full lifetime of the component. React ensures you get the same ref object back on every render.
  
  
  ⚠️When Should You Mutate ref.current?
Since mutating ref.current doesn't cause a re-render, it's important when you perform the mutation.
- ✅Safe: Inside event handlers (like - onClick,- onChange) or inside- useEffecthooks. These run after the render cycle is complete or as a result of user interaction, making mutations predictable.
- ❌Avoid (Generally): Mutating - ref.currentdirectly during the rendering phase (i.e., right inside the main body of your functional component). While React won't stop you, reading a ref during render is fine, but writing to it can make component behavior less predictable. This is because the component body should ideally be free of side effects, and mutations might not behave consistently depending on React's rendering optimizations (like Concurrent Mode). If you need to calculate something based on render and store it mutably,- useEffectis usually the better place.
🔧Common Use Cases
useRef serves two primary purposes in React components:
1. Accessing DOM Nodes
This is a very common use case. useRef allows you to get a direct reference to a specific DOM element rendered by your component.
- 
How it works: - Create a ref, usually initialized to null: const myInputRef = useRef(null);
- Attach this ref to a JSX element using the special ref prop: .
- After the component mounts and React creates the DOM node for the , React will setmyInputRef.currentto that DOM node instance.
 
- Create a ref, usually initialized to null: 
- 
Why it's needed: 
 For interacting directly with the DOM, which is sometimes necessary for:- Managing focus (e.g.- myInputRef.current.focus()).
- Measuring element dimensions or position.
- Triggering imperative animations.
- Integrating with third-party libraries that need direct DOM access.
 
- Managing focus (e.g.- 
import React, { useRef, useEffect } from 'react';
function TextInputWithFocusButton() {
  // 1. Create a ref to hold the input DOM element
  const inputEl = useRef(null);
  // Example: Focus on initial mount 
  useEffect(() => {
    inputEl.current?.focus();     
  }, []);                 
  // Empty dependency array means run once after initial mount
  return (
    <>
      {/* 2. Attach the ref to the input element */}
      <input ref={inputEl} type="text" />
    >
  );
}2. Storing Mutable Values (Like Instance Variables)
You can use useRef to keep track of any mutable value that needs to persist across renders but should not cause a re-render when it changes.
- Storing previous state or prop values.
- Managing timer IDs (e.g., from setTimeoutorsetInterval).
- Keeping track of internal component state that doesn't directly affect the rendered output. 
- 
How it works: - 
Initialization: 
You call useRef(initialValue)during your component's setup. React creates a plain JavaScript object like{ current: initialValue }.
- 
Persistence: 
React internally holds onto this specific object for the entire lifetime of your component instance. On every subsequent render, the exact same object is returned by the useRefhook.
- 
Accessing: 
You can read the stored value anytime using yourRef.current.
- 
Updating: 
You can change the stored value by directly assigning a new value to the .current property(e.g.,yourRef.current = newValue).
 
- 
Initialization: 
You call 
⚠️No Re-render: this assignment to
.currentis just a standard JavaScript object property mutation. React does not monitor this change, and therefore, it does not trigger a component re-render. The value is updated silently within the persistent ref object.
The Analogy: The Room, The Closet, and The Label Maker
Imagine your React component is like a room. Every time the component "re-renders" (because its state or props change), it's like the room gets quickly dismantled and rebuilt with the updated information.
- useState: Think of- useStateas the visible furniture or decorations in the room (like a couch or a painting). When you change something using the- setfunction (e.g., changing the couch color), React notices this visible change and rebuilds the room (re-renders the component) to show the update. Everyone sees the new couch color.
- useRef: Now,- useRefgives you access to persistent tools that don't cause a room rebuild when used or changed. It primarily provides two kinds of tools:
The Hidden Storage Closet (for Mutable Values):
- Calling useRef(initialValue)can create a small, hidden storage closet inside the room, with an initial item placed on its single shelf, labelled.current.
- This closet (refobject) and its contents persist across room rebuilds (re-renders). Even when the room is dismantled and rebuilt, the closet remains exactly where it is, untouched.
- You can open the closet anytime (preferably in effects or handlers) and change the item on the .currentshelf (myRef.current = newValue).
- Crucially: Changing the item inside the hidden closet does not cause the room to be rebuilt (it does not trigger a re-render). It's a silent change, hidden from the main rendering process.
The Persistent Label Maker (for DOM Access):
- Calling useRef(null)can also give you a persistent label maker.
- When you build the room, you can use the special refprop on a specific part of the room's structure (like a window, a door, or a light switch – representing a DOM element like). This tells React: "Use themyReflabel maker to put a unique, persistent label on this specific window when you build it."
- After the room is built (the component mounts and renders the element), the label maker's display (myRef.current) now points directly to that specific, labeled window (the actual DOM node).
- You can then use this reference (myRef.current) to interact directly with that specific part of the room (e.g.,myRef.current.focus()to look through the window, ormyRef.current.style.display = 'none'to cover it) without needing to rebuild the entire room (no re-render is triggered by accessing or manipulating the element via the ref).
In essence, useRef provides ways to either hold onto information silently (closet) or get a direct, persistent handle (label maker) to parts of the rendered output, all without interfering with React's normal state-driven rendering cycle.
  
  
  🔄 useState vs useRef – Quick Comparison
| Feature | useState | useRef | 
|---|---|---|
| Triggers re-render on change? | ✅ Yes | ❌ No | 
| Persists across renders? | ✅ Yes | ✅ Yes | 
| Used for DOM access? | ❌ No | ✅ Yes | 
| Ideal for | UI-related state that affects rendering | Mutable values or DOM refs that don’t affect UI | 
| How to update value | Using setter function (e.g., setValue()) | Direct mutation ( myRef.current = newValue) | 
| Can be used in render phase? | ✅ Yes (safe) | ⚠️ Reading: Yes / Writing: Avoid in render phase | 
Wrapping Up
useRef is a powerful tool in your React toolkit, essential for interacting with the DOM and managing persistent mutable values that shouldn't trigger re-renders. Understanding when and why to use it over useState is key to writing efficient and effective React components.
  
  
  when and why to use useRef:
- You need direct access to a DOM element for imperative actions like focusing, measuring, or integrating with external libraries. useStatecannot do this.
- You need to store mutable data that persists across renders, but changing this data should NOT cause a re-render. This is useful for performance or specific logic needs.
- Think: Timer IDs (setTimeout/setInterval), tracking previous state/props, flags not directly rendered.
In short: useState is for state that drives your UI updates. useRef is for references to DOM nodes or for holding mutable data silently behind the scenes.
Likes, Comments and feedback are welcome!😅
Happy coding!