Dev.to WebDev 🛠 Dev 👁 0 📖 4 min read

React Mastery Series – Day 14: React Hooks Deep Dive – Understanding useRef and useMemo

Welcome back to the React Mastery Series! In the previous article, we explored useEffect Hook and learned how React handles side effects such as: API calls Timers Event listeners WebSocket connections Cleanup operatio

Welcome back to the React Mastery Series!

In the previous article, we explored useEffect Hook and learned how React handles side effects such as:

  • API calls
  • Timers
  • Event listeners
  • WebSocket connections
  • Cleanup operations

Today, we will explore two more powerful React Hooks:

useRef and useMemo

These Hooks are frequently used in production applications to:

  • Access DOM elements
  • Store values without triggering re-renders
  • Optimize expensive calculations
  • Improve application performance

Understanding useRef Hook

useRef is a React Hook that allows us to store a value that persists across renders without causing the component to re-render.

Syntax:

const reference = useRef(initialValue);

The returned object looks like:

{
  current: initialValue
}

The value is accessed using:

reference.current

useRef vs useState

A common question:

Why do we need useRef when we already have useState?

The difference:

useState useRef
Updates trigger re-render Updates do not trigger re-render
Used for UI data Used for storing values
React tracks changes React does not track changes

Example:

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

Updating:

setCount(count + 1);

causes:

State Update
      |
      ↓
Component Re-render

With useRef:

const count = useRef(0);

Updating:

count.current++;

does:

Value Updated
      |
      ↓
No Re-render

Using useRef to Access DOM Elements

One of the most common use cases of useRef is accessing DOM elements directly.

Example:

import { useRef } from "react";

function SearchBox() {
  const inputRef = useRef();

  function focusInput() {
    inputRef.current.focus();
  }

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

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

Flow:

Button Click
      |
      ↓
focusInput()
      |
      ↓
inputRef.current
      |
      ↓
Input DOM Element
      |
      ↓
focus()

Real-World Example: Login Page

Imagine a banking login page.

When the page loads:

Open Login Page
        |
        ↓
Username Field Automatically Focused

Implementation:

useEffect(()=>{
  usernameRef.current.focus();
},[]);

This improves user experience.

Storing Previous Values Using useRef

useRef can store previous values.

Example:

function Profile({ name }) {
  const previousName = useRef();

  useEffect(() => {
    previousName.current = name;
  }, [name]);

  return (
    <div>
      Current:
      {name}
      <br />
      Previous:
      {previousName.current}
    </div>
  );
}

The value survives between renders.

Tracking Render Count

Example:

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

  renderCount.current++;

  return (
    <p>
      Render Count:
      {renderCount.current}
    </p>
  );
}

Unlike state, updating this value does not trigger another render.

Storing Timer References

Example:

function Timer() {
  const timerRef = useRef();

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

  function stopTimer() {
    clearInterval(timerRef.current);
  }
}

Common use cases:

  • Countdown timers
  • Debounce logic
  • Polling APIs

Real-World Example: WebSocket Connection

In enterprise applications:

Dashboard Open
       |
       ↓
Create WebSocket
       |
       ↓
Store Connection Reference
       |
       ↓
Receive Messages
       |
       ↓
Close Connection

Example:

const socketRef = useRef(null);

useEffect(() => {
  socketRef.current = new WebSocket("wss://example.com");

  return () => {
    socketRef.current.close();
  };
}, []);

Understanding useMemo Hook

Now let's explore:

useMemo

useMemo is used to optimize expensive calculations by memorizing a computed value.

Syntax:

const result = useMemo(
  () => calculation,
  [dependencies]
);

React remembers the result and recalculates only when dependencies change.

Why Do We Need useMemo?

Consider:

function ProductList() {
  const products = calculateProducts();

  return <Product products={products} />;
}

Every render:

Component Render
        |
        ↓
calculateProducts()
        |
        ↓
Heavy Calculation

Even when data has not changed.

This can impact performance.

Using useMemo

Example:

const filteredProducts = useMemo(() => {
  return products.filter((product) => product.price > 1000);
}, [products]);

Now:

products unchanged
        |
        ↓
Use Previous Result


products changed
        |
        ↓
Recalculate

useMemo Example: Expensive Calculation

Without useMemo:

function App() {
  const result = heavyCalculation(value);

  return <h1>{result}</h1>;
}

The calculation runs on every render.

With useMemo:

function App() {
  const result = useMemo(() => {
    return heavyCalculation(value);
  }, [value]);

  return <h1>{result}</h1>;
}

The calculation runs only when value changes.

useMemo with Search Filtering

Real-world example:

const filteredUsers = useMemo(() => {
  return users.filter((user) => user.name.includes(searchText));
}, [users, searchText]);

Used in:

  • User management systems
  • Product search
  • Transaction filtering

useMemo vs useEffect

A common confusion.

useEffect

Used for:

  • API calls
  • Side effects
  • External systems

Example:

useEffect(()=>{
  fetchUsers();
},[]);

useMemo

Used for:

  • Calculating values
  • Performance optimization

Example:

const total = useMemo(()=>{
  return calculateTotal(items);
},[items]);

useMemo vs useCallback

These Hooks are related but different.

Hook Purpose
useMemo Memoize values
useCallback Memoize functions

Example:

useMemo:

const total = useMemo(()=>calculateTotal(),[]);

useCallback:

const handleClick = useCallback(()=>{
 saveData();
},[]);

We will explore useCallback in detail in the next article.

Real-World Example: Banking Dashboard

Imagine a dashboard displaying:

  • Account summary
  • Transaction history
  • Spending analysis

Data:

Transactions
      |
      ↓
Calculate Monthly Spending
      |
      ↓
Generate Chart Data
      |
      ↓
Render Dashboard

Without optimization:

Every UI update
        |
        ↓
Recalculate Everything

With useMemo:

Transactions Changed
        |
        ↓
Recalculate Chart Data

Otherwise

Reuse Previous Calculation

Common Mistakes

1. Using useMemo Everywhere

Incorrect:

const name = useMemo(()=>user.name,[user]);

This creates unnecessary complexity.

Use useMemo only for:

  • Expensive calculations
  • Performance issues

2. Incorrect Dependencies

Example:

useMemo(()=>{
 return calculate(items);
},[]);

Problem:

items is missing.

Correct:

useMemo(()=>{
  return calculate(items);
},[items]);

3. Mutating useRef Values Expecting UI Updates

Example:

count.current++;

The UI will not update.

Use:

setCount()

when UI should change.

Best Practices

  • Use useRef for persistent mutable values.
  • Use useRef when you need DOM access.
  • Use useMemo only for expensive computations.
  • Do not optimize prematurely.
  • Keep dependency arrays accurate.
  • Measure performance before optimization.

Key Takeaways

Today, we learned:

✅ useRef stores values without causing re-renders.
✅ useRef can access DOM elements directly.
✅ useMemo caches expensive calculations.
✅ useMemo improves performance when used correctly.
✅ useState, useEffect, useRef, and useMemo solve different problems.

Coming Next 🚀

In Day 15, we will explore:

React Hooks Deep Dive – useCallback and React.memo

We will learn:

  • Function memoization
  • Preventing unnecessary child renders
  • React.memo optimization
  • Passing callbacks efficiently
  • Performance optimization patterns
  • Real-world component optimization

These concepts are extremely important when building large-scale React applications.

Happy Coding! 🚀

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.