惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
Cloudbric
Cloudbric
云风的 BLOG
云风的 BLOG
A
About on SuperTechFans
The GitHub Blog
The GitHub Blog
IT之家
IT之家
F
Full Disclosure
B
Blog RSS Feed
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Hugging Face - Blog
Hugging Face - Blog
B
Blog
H
Help Net Security
The Cloudflare Blog
Recorded Future
Recorded Future
P
Proofpoint News Feed
P
Proofpoint News Feed
C
Cisco Blogs
T
Tailwind CSS Blog
P
Palo Alto Networks Blog
D
Docker
爱范儿
爱范儿
Know Your Adversary
Know Your Adversary
博客园 - 聂微东
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Y
Y Combinator Blog
雷峰网
雷峰网
AWS News Blog
AWS News Blog
D
DataBreaches.Net
博客园 - 司徒正美
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - Franky
C
Cybersecurity and Infrastructure Security Agency CISA
Blog — PlanetScale
Blog — PlanetScale
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Latest news
Latest news
Google DeepMind News
Google DeepMind News
Martin Fowler
Martin Fowler
MongoDB | Blog
MongoDB | Blog
C
CERT Recently Published Vulnerability Notes
阮一峰的网络日志
阮一峰的网络日志
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
C
CXSECURITY Database RSS Feed - CXSecurity.com
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Cyber Attacks, Cyber Crime and Cyber Security
腾讯CDC
小众软件
小众软件
G
Google Developers Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Scott Helme
Scott Helme
O
OpenAI News

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Mastering useRef in React: The Hook That Gives React Memory Without Re-Rendering
Kathirvel S · 2026-05-20 · via DEV Community

When developers first learn React, most of the focus goes toward useState.

Because state changes update the UI.

Buttons update.

Counters increase.

Forms react instantly.

Everything feels connected.

But after building larger applications, one important question appears:

What if we need to store something inside a component, but we do NOT want React to re-render the component every time it changes?

That exact problem led to the creation of useRef.

And this is where many developers suddenly realize:

useRef is not just another hook.

It is one of React’s most important performance tools.

It allows components to:

  • Remember values across renders
  • Access real DOM elements
  • Store mutable data
  • Avoid unnecessary re-renders
  • Preserve values silently in memory
  • Handle timers, scrolling, focus, animations, and external libraries

The interesting part is:

Most developers use only a tiny portion of what useRef can actually do.

They think refs are only for focusing inputs.

But internally, refs are much more powerful than that.

In this 11th episode of “Let’s Master React Hooks Together”, we are going far beyond the basic understanding of useRef.

We will deeply understand:

  • What useRef actually is
  • Why React created it
  • The core problem it solves
  • How React stores refs internally
  • Why refs don’t trigger re-renders
  • How refs differ from state
  • Real-world use cases
  • Performance benefits
  • Hidden behaviors
  • Advanced patterns
  • Common mistakes developers make

And by the end, you’ll understand not only how to use useRef, but also how React itself thinks about refs internally.


What is useRef in React?

According to the official React definition:

useRef is a React Hook that lets you reference a value that’s not needed for rendering.

Syntax:

const ref = useRef(initialValue)

Enter fullscreen mode Exit fullscreen mode

React returns an object like this:

{
  current: initialValue
}

Enter fullscreen mode Exit fullscreen mode

Example:

const countRef = useRef(0)

Enter fullscreen mode Exit fullscreen mode

Now React creates an object internally:

{
  current: 0
}

Enter fullscreen mode Exit fullscreen mode

And the important thing is:

React keeps this same object alive between renders.

Not a copy.

Not a new object.

The exact same object.

Only the value inside .current changes.

That detail is the entire foundation of how refs work.


Why Does React Need useRef?

To understand this properly, we need to first understand how React components work internally.

Every time a component re-renders:

  • The entire component function executes again
  • Local variables are recreated
  • Function memory resets

Example:

function App() {
  let count = 0

  console.log(count)
}

Enter fullscreen mode Exit fullscreen mode

Every render creates:

count = 0

Enter fullscreen mode Exit fullscreen mode

again and again.

The variable does NOT survive renders.

This creates a huge problem.

Sometimes applications need values that must:

  • Persist between renders
  • Stay in memory
  • Avoid UI updates
  • Avoid expensive re-renders

Examples:

  • Timer IDs
  • Previous values
  • Scroll positions
  • Input references
  • Animation states
  • External library instances

Using state for these values becomes inefficient.

Because state updates trigger rendering.

And rendering is expensive when unnecessary.

This is exactly where useRef enters.

React needed a way to:

Store persistent mutable values without re-rendering the UI.

That solution became useRef.


The Core Problem useRef Solves

Imagine a large dashboard application.

You are storing a timer ID:

const [timerId, setTimerId] = useState()

Enter fullscreen mode Exit fullscreen mode

Every time the timer changes:

  • State updates
  • Component re-renders
  • Child components may re-render
  • Virtual DOM comparisons happen again

But the UI never even displays the timer ID.

So why re-render?

There is absolutely no reason.

That render becomes wasted work.

Now imagine using:

const timerRef = useRef()

Enter fullscreen mode Exit fullscreen mode

Now:

  • Value updates silently
  • No re-render happens
  • React skips unnecessary work
  • Performance improves

This is one of the biggest optimization ideas inside React.


The Real Mental Model of useRef

Most tutorials say:

“Refs store values.”

But that understanding is incomplete.

A better mental model is this:

useRef is a persistent memory container that React does not track for rendering.

That single sentence explains everything.

React knows the ref exists.

But React does NOT monitor .current for UI updates.

That means:

ref.current = 100

Enter fullscreen mode Exit fullscreen mode

does not tell React:

“Hey, render again.”

React simply ignores it.

That is why refs are extremely fast.


useState vs useRef — The Deep Difference

At surface level:

useState useRef
Triggers re-render Does NOT trigger re-render
Used for UI updates Used for mutable storage
Reactive Non-reactive
React tracks changes React ignores .current changes

But internally, the difference is much deeper.


What Happens When State Changes?

setCount(count + 1)

Enter fullscreen mode Exit fullscreen mode

React sees:

  • State changed
  • UI may need updating
  • Component must re-render

So React schedules rendering work.


What Happens When Ref Changes?

countRef.current += 1

Enter fullscreen mode Exit fullscreen mode

React sees nothing.

Because refs are mutable containers.

React does not compare .current.

So no render happens.

This is why refs are ideal for invisible internal data.


Understanding useRef Through a Counter


Counter Using State

import { useState } from "react"

function Counter() {
  const [count, setCount] = useState(0)

  const increment = () => {
    setCount(count + 1)
  }

  return (
    <div>
      <h1>{count}</h1>

      <button onClick={increment}>
        Increment
      </button>
    </div>
  )
}

Enter fullscreen mode Exit fullscreen mode

Flow:

  1. Button clicked
  2. setCount() runs
  3. State changes
  4. React schedules re-render
  5. Component executes again
  6. New UI appears on screen

State is deeply connected to rendering.

That is why UI updates happen instantly.


Counter Using Ref

import { useRef } from "react"

function Counter() {
  const countRef = useRef(0)

  const increment = () => {
    countRef.current += 1

    console.log(countRef.current)
  }

  return (
    <div>
      <button onClick={increment}>
        Increment
      </button>
    </div>
  )
}

Enter fullscreen mode Exit fullscreen mode

Flow:

  1. Button clicked
  2. .current changes
  3. React ignores the change
  4. Component does NOT re-render
  5. Value still persists internally

This is the first moment developers truly understand refs.

The value changes.

But the UI remains unchanged.

Because refs are not connected to rendering.


Why .current Exists Instead of Direct Values

A common question:

Why not simply do this?

const ref = 0

Enter fullscreen mode Exit fullscreen mode

Because React needs a stable object reference.

If React returned raw values:

  • Values would reset every render
  • References would break
  • Persistence would disappear

Instead, React creates one stable object:

{
  current: value
}

Enter fullscreen mode Exit fullscreen mode

Then React preserves that object forever during the component lifecycle.

Only .current changes.

This is why refs survive renders.


Accessing DOM Elements with useRef

One of the most famous use cases.

Example:

import { useRef } from "react"

function FocusInput() {
  const inputRef = useRef()

  const focusInput = () => {
    inputRef.current.focus()
  }

  return (
    <div>
      <input ref={inputRef} />

      <button onClick={focusInput}>
        Focus Input
      </button>
    </div>
  )
}

Enter fullscreen mode Exit fullscreen mode

Chain of what happens:

  1. React renders <input />
  2. React creates actual DOM node
  3. React stores DOM node inside inputRef.current
  4. Button clicked
  5. focusInput() executes
  6. .focus() runs on real DOM element
  7. Browser focuses the input instantly

This is direct communication with the DOM.

Without refs, React components normally stay abstracted away from real DOM access.

Refs create that bridge.


Why Direct DOM Access Matters

React normally follows declarative UI.

Meaning:

<input />

Enter fullscreen mode Exit fullscreen mode

describes what UI should look like.

But some browser features require imperative control.

Examples:

  • Focus
  • Scrolling
  • Text selection
  • Playing videos
  • Canvas drawing
  • Animations

Refs make these actions possible.


Storing Previous Values Using useRef

This is one of the smartest real-world patterns.

import { useEffect, useRef } from "react"

function Example({ value }) {
  const previousValue = useRef()

  useEffect(() => {
    previousValue.current = value
  }, [value])

  return (
    <div>
      <h2>Current: {value}</h2>
      <h2>Previous: {previousValue.current}</h2>
    </div>
  )
}

Enter fullscreen mode Exit fullscreen mode

How this works internally:

  1. Component renders
  2. previousValue.current initially empty
  3. useEffect runs after render
  4. Current value stored inside ref
  5. Next render happens
  6. Old value still exists inside ref
  7. Previous value becomes accessible

This pattern is extremely useful in:

  • Form comparisons
  • Analytics tracking
  • Detecting value changes
  • Undo systems
  • Animations

Managing Timers Without Re-Renders

Bad approach:

const [timerId, setTimerId] = useState()

Enter fullscreen mode Exit fullscreen mode

Every timer update triggers rendering.

Completely unnecessary.

Better approach:

const timerRef = useRef()

Enter fullscreen mode Exit fullscreen mode

Example:

timerRef.current = setInterval(() => {
  console.log("Running")
}, 1000)

Enter fullscreen mode Exit fullscreen mode

Later:

clearInterval(timerRef.current)

Enter fullscreen mode Exit fullscreen mode

Flow:

  1. Timer created
  2. ID stored in ref
  3. Ref updates silently
  4. No render triggered
  5. Timer remains accessible anytime

This is efficient React architecture.


Tracking Render Count

import { useRef, useEffect } from "react"

function App() {
  const renderCount = useRef(0)

  useEffect(() => {
    renderCount.current += 1
  })

  return (
    <h1>Renders: {renderCount.current}</h1>
  )
}

Enter fullscreen mode Exit fullscreen mode

Interesting behavior:

  • Updating ref does not re-render
  • But effect runs after every render
  • Ref silently remembers count

This becomes incredibly useful while debugging performance issues.


Solving Stale Closure Problems

One of the most advanced useRef use cases.

Problem:

setInterval(() => {
  console.log(count)
}, 1000)

Enter fullscreen mode Exit fullscreen mode

Sometimes intervals capture old state values.

Meaning:

The interval keeps reading outdated data.

Solution:

const countRef = useRef(count)

useEffect(() => {
  countRef.current = count
}, [count])

Enter fullscreen mode Exit fullscreen mode

Now interval reads:

countRef.current

Enter fullscreen mode Exit fullscreen mode

Flow:

  1. State updates
  2. Effect runs
  3. Latest value copied into ref
  4. Interval accesses ref
  5. Interval always gets newest value

This pattern is heavily used in real-time systems.


useRef Is Actually About Performance

Most people think refs are mainly for DOM access.

That is only a small part.

The deeper purpose is performance optimization.

Because unnecessary rendering is expensive.

Especially in:

  • Large dashboards
  • Complex forms
  • Realtime applications
  • Charts
  • Data-heavy UIs

Refs help avoid render cycles for data that users never even see.

This keeps React applications faster and cleaner.


When You SHOULD Use useRef

Use refs when:

✅ Value should persist
✅ UI does NOT depend on the value
✅ Re-rendering is unnecessary
✅ You need DOM access
✅ You manage timers or intervals
✅ You store previous values
✅ You integrate third-party libraries


When You Should NOT Use useRef

Avoid refs when:

❌ UI depends on the value
❌ User should see updates instantly
❌ Data drives rendering
❌ Reactive updates are needed

In those cases:

Use state.

Because state exists specifically for rendering logic.


The Biggest Secret About useRef

Here is the hidden truth many developers miss:

useRef is one of the few hooks that gives you mutable memory inside React’s functional world.

Normally functional components are recreated every render.

But refs break that limitation.

They allow values to survive independently from rendering.

That makes refs feel almost like instance variables from class components.

And this is exactly why advanced React developers rely on refs heavily in performance-sensitive systems.


Final Thoughts

Understanding useRef changes the way you think about React.

Because now you realize:

Not every changing value belongs in state.

Some values are meant only for memory.

Some values are meant only for logic.

Some values should exist silently in the background without forcing React to repaint the UI repeatedly.

And that is precisely the role of useRef.

It gives React components memory without rendering pressure.

That balance between persistence and performance is what makes refs incredibly powerful.


Conclusion

That’s it for Episode 11 of the series: “Let’s Master React Hooks Together”

At first glance, useRef may appear tiny compared to hooks like useState or useEffect.

But after understanding it deeply, something becomes clear:

useRef is not just another React hook.

It is one of the core building blocks behind performant React applications.

Because real-world React development is not only about rendering UI.

It is also about controlling memory, preserving values, avoiding unnecessary renders, and managing behavior efficiently behind the scenes.

And that is exactly what refs are designed for.

You now deeply understand:

  • What useRef really is
  • Why React created it
  • The rendering problem it solves
  • How refs work internally
  • Why refs don’t trigger re-renders
  • How React preserves refs
  • DOM access patterns
  • Performance optimization strategies
  • Advanced real-world use cases
  • Stale closure solutions
  • Previous value tracking
  • Common mistakes developers make
  • The hidden philosophy behind refs

More importantly, you now understand a deeper React principle that changes how applications are designed:

React rendering should happen only when the UI actually needs updating.

That single idea is the foundation of scalable React architecture.

And useRef plays a massive role in achieving that balance.

The moment developers stop putting every changing value into state is usually the moment they start writing cleaner, smarter, and more optimized React applications.

Because mastering React is not only about making things work.

It’s about understanding:

  • what should trigger rendering,
  • what should persist silently,
  • and how React manages both worlds internally.

And useRef sits exactly at the center of that understanding.

See you in the next episode of “Let’s Master React Hooks Together”, where we continue exploring the deeper mechanics behind React Hooks and uncover how React