While coding with React, I almost never touched this particular React Hook: useRef. Maybe it's more commonly used for controlling events like mouse interactions or similar. But here's the real question: why have I never used it in the past 2 years?

In my mind:

There's no way I'd skip learning a hook that's supposedly powerful if it was that important.

Then I remembered that many of my developer friends often said:

"Be careful with useRef it can slow down your app."

Maybe that's also why I thought:

“Well then, no need to learn it if it's going to make things slow.”

Until one day... I encountered a case at work that forced me to use useRef. And surprisingly... the result was quite shocking in terms of performance!


How Does useRef Work?

Under the hood, useRef uses the JavaScript Closure concept — allowing us to store data references outside the React render cycle. Simply put: a function can store and access data even when it's outside the render context.

useRef React Hook

Source: React useRef Source Code

useRef stores an object like { current: ... } which is mutable — it can be changed directly without triggering a re-render.

const ref = useRef(initialValue);
ref.current = 'your value';

Does useRef Cause Slowness?

Theoretically, no, because:

  • useRef doesn’t trigger a re-render like useState or useEffect.
  • When ref.current is updated, React doesn’t care or perform reconciliation.

This makes useRef efficient — because it avoids the expensive re-rendering process.


React Rendering Process in Short

To understand further, we need to grasp how React renders:

  1. Component Initialization

    React creates a component instance and executes it to produce React Elements.

  2. Creating New Virtual DOM

    React builds the Virtual DOM from the render result.

  3. Diffing Algorithm

    React compares the new and old Virtual DOM.

  4. Reconciliation

    React identifies the changes and only updates the changed parts in the DOM.

  5. Lifecycle & Side Effects

    Hooks like useState, useEffect are executed after the DOM updates.

Now, useState will retrigger this entire process when the value changes. But useRef? No. Since it only stores references and doesn’t interact with the Virtual DOM — it’s much more efficient!


So, Why Do People Say useRef Can Be Slow?

Back to the original question.

The answer: potential memory leaks.

React (and JavaScript in general) uses a garbage collector. But if we carelessly store large data in a ref without cleaning it up, that data won’t be cleared from memory.

Eventually...

BOOM! Memory leak.


Real Case at My Office

At work, I once had a case where:

  • I had to handle HTML string input that could reach up to 5MB.
  • In our business logic, there was a refetch process in the code. Refetching could overwrite saved state if there was no external storage or isolated state. In this case, useRef became a solution since it’s not tied to the render lifecycle like useState.
  • When I used useRef, the input could be stored without triggering a re-render and ran much faster, because there was no need for expensive re-renders.

However... when the ref wasn't cleaned up properly, a memory leak occurred instantly.

// cleanup ref
useEffect(() => {
  return () => {
    ref.current = null;
  };
}, []);

Here's a simulation illustrating this situation:

Garbage Collector Simulation

Source: React useRef Real Case


Conclusion

  • useRef is very useful, especially for storing data that doesn’t need to trigger a re-render.
  • But be cautious: the data inside a ref is not automatically cleaned up by React.
  • Use useRef wisely, especially when dealing with large data or many DOM references.
  • Most importantly: understand the context — don’t just avoid it because someone said it’s slow.

If you’re still confused, feel free to ask questions in the comments. And if there's any mistake in this article, I'm more than open to corrections 😊