DEV Community

Cover image for Today I Truly Understood the useRef Hook (Not Just What It Does, But Why It Exists)
Usama
Usama

Posted on

Today I Truly Understood the useRef Hook (Not Just What It Does, But Why It Exists)

Today’s learning was one of those moments where a hook I had been using casually suddenly clicked at a deeper level.

I had used useRef before.
I knew it “stores something” and “doesn’t cause re-renders”.

But today, while working on my project, I finally understood:

useRef is not about rendering. It’s about persistence and control outside React’s render cycle.

Two real problems in my app taught me this.


Problem 1: Focusing the Search Input with the Keyboard

I wanted a simple behavior:

  • When the user presses Enter
  • If the input is not already focused
  • Then:

    • Focus the input
    • Clear the search query

To do this properly, I needed direct access to the DOM element.

That’s where useRef comes in.

The core idea looked like this:

const inputEl = useRef(null);
Enter fullscreen mode Exit fullscreen mode

And in JSX:

ref={inputEl}
Enter fullscreen mode Exit fullscreen mode

Now I had a permanent reference to the input element.

Inside my effect, I added a keydown listener:

if (document.activeElement === inputEl.current) return;

if (e.key === "Enter") {
  inputEl.current.focus();
  setQuery("");
}
Enter fullscreen mode Exit fullscreen mode

The Important Realization

inputEl.current is not state.
It changes, but React does not re-render.

And that is exactly what we want.

We’re not describing UI here.
We’re controlling the environment.


useRef Is Not for UI. It’s for Escape Hatches.

This was my first big mental shift today.

State = describes what should be on screen
Ref = stores values or elements outside the render logic

Focusing an input is not a rendering concern.
It’s a side effect.

So useRef is the perfect tool.


Problem 2: Counting Something Without Causing Re-Renders

The second place where things clicked was this:

const countRef = useRef(0);
Enter fullscreen mode Exit fullscreen mode

And then:

if (userRating) countRef.current++;
Enter fullscreen mode Exit fullscreen mode

This value:

  • Persists between renders
  • Updates over time
  • But does not trigger a re-render

This Is Huge

If I had used useState here:

  • The component would re-render
  • The UI would change
  • The logic would be tied to rendering

But with useRef:

I get memory without reactivity.

That’s a powerful concept.


The Real Mental Model of useRef

Today I finally internalized this:

useRef is a box that React never looks inside.

  • You can put anything in it
  • You can mutate it
  • React does not care
  • It survives re-renders
  • But it never causes one

How I Think About useRef Now

I now see three main use cases:

  • Accessing DOM elements (focus, scroll, measure, etc.)
  • Storing values between renders without re-rendering
  • Keeping mutable values for effects, timers, counters, previous values

The Difference Between useState and useRef (In One Line)

State is for UI
Ref is for logic and control


A Small Hook, A Big Shift in Thinking

Before today, I thought:

“useRef is just for DOM”

Now I understand:

“useRef is for anything that must persist but must not affect rendering

That’s a huge architectural difference.


Final Thoughts

Today wasn’t about learning a new hook.

It was about learning how React thinks.

Not everything belongs in state.
Not everything should cause a re-render.
Some things just need to exist.

And that’s exactly what useRef is for.

I’m still learning. Still refining.
But today, useRef stopped being a trick and became a tool I truly understand.

Top comments (0)