The Forge LogoThe Forge Logo

© 2026 Youssef Elmohamadi The Forge. All rights reserved.

ON THIS PAGE

useRef in React: The Magic Behind That Tiny Object

1 month ago
5 min read
114
Share Article:

Introduction

When working with React, there are times when you need to store a value that survives re-renders, but you don't want changes to that value to trigger another render. That's exactly where useRef comes in. Most developers use it like this:

javascript
1import { useRef } from "react";
2const ref = useRef(0);

But have you ever wondered what actually happens under the hood?

The Surprising Truth: It's Just an Object

At its core, useRef is incredibly simple. When React creates a ref, it returns a plain JavaScript object with a single property called current:

javascript
1{ 
2current: 0 
3}

That's it. No magic. No complex data structure. Just an object. Because of this, refs are mutable, meaning you can directly update the value stored inside current:

javascript
1ref.current = 10;

Unlike state updates, React doesn't track these changes for rendering purposes. The value changes immediately in memory, but React won't re-render your component.

Why Doesn't React Re-render?

Compare this with state:

javascript
1const [count, setCount] = useState(0);

When you call: setCount(1); React schedules a new render because state is part of the component's rendering process. Refs work differently. Updating: ref.current = 1; simply mutates an object that React keeps around between renders. Since React isn't asked to update the UI, no re-render happens.

State vs Ref

State Triggers a re-render when updated. Immutable from React's perspective. Must be updated through the setter function. Used for values that affect the UI. setCount(prev => prev + 1); Ref Does not trigger a re-render. Mutable. Can be updated directly. Ideal for storing values that don't need to be displayed. countRef.current += 1;

content image 1

The Important Rule Most Developers Miss

A common misconception is treating refs like state. React state behaves as a snapshot. Every render receives its own stable version of state values. Refs are different. Because ref.current can change at any moment, reading or writing it during rendering can make your component unpredictable. ❌ Avoid this:

javascript
1function Component() {
2 const countRef = useRef(0);
3 countRef.current++;
4 return <div>{countRef.current}</div>;
5 }

The component's output can become difficult to reason about.

The Golden Rule

Use refs inside: Event handlers Effects (useEffect) Imperative DOM operations Examples:

javascript
1buttonRef.current.focus();
2useEffect(() => {
3  previousValue.current = value;
4}, [value]);
5const handleClick = () => {
6  clickCount.current++;
7};

These are predictable places where refs shine.

When Should You Use useRef?

Some common use cases include: Accessing DOM elements directly Storing interval or timeout IDs Keeping track of previous values Persisting mutable values between renders Integrating with third-party libraries

Final Takeaway

useRef isn't some mysterious React feature. Under the hood, it's simply:

javascript
1{ 
2current: value
3}

The real power comes from the fact that React preserves the same object between renders while allowing you to mutate its current property without triggering a re-render. Think of it this way: State is for data that drives the UI. Ref is for data you want React to remember without re-rendering. Understanding this distinction is what separates React users from React developers.

Thank You for reading

by-- Youssef El-Mohammadi

Enjoyed the read? Share it!

Share Article: