Skip to main content

Command Palette

Search for a command to run...

Use Ref Previous Value

Published
3 min read

Using useRef to Track the Previous State in React

In React, when working with the useState hook, there might be situations where you need to access the previous value of the state. However, React's useState doesn't inherently provide a way to retrieve the previous value. Fortunately, with the help of the useRef hook, you can easily track and store the previous state value.

Why Use useRef for Previous State?

  • Avoid Extra Re-renders: Unlike useState, updating a useRef value doesn’t cause a component re-render. This makes it ideal for storing non-UI values like the previous state.

  • Persist Data Across Renders: The .current property of a useRef object persists between renders, making it perfect for storing values like the previous state.

  • Lightweight and Simple: It provides an easy-to-understand and efficient way to handle this scenario.

Step-by-Step Implementation

Here’s how you can use useRef to track the previous state value:

import React, { useState, useEffect, useRef } from "react";

function App() { const [count, setCount] = useState(0); const prevCountRef = useRef(null); // Create a ref to store the previous value

// Update the ref with the current value after each render useEffect(() => { prevCountRef.current = count; });

const prevCount = prevCountRef.current; // Access the previous value

return (

Current Count: {count}

Previous Count: {prevCount}

<button onClick={() => setCount(count + 1)}>Increase <button onClick={() => setCount(count - 1)}>Decrease

); }

export default App;

Explanation

  1. useRef for Storage:

    • prevCountRef is initialized using useRef(null) to hold the previous value of count.
  2. Update in useEffect:

    • The useEffect runs after every render, updating the prevCountRef.current with the latest value of count.
  3. Access Previous Value:

    • The previous value is accessible via prevCountRef.current before it gets updated in the next render.

When to Use This Pattern

This pattern is useful in scenarios where you need to compare the current and previous state values, such as:

  • Logging Changes: Track and log when a state value changes.

  • Conditional Operations: Execute actions based on differences between the current and previous values.

  • UI Animations: Perform animations when specific values change.

Real-World Example: Tracking Color Changes

Let’s say you have an app where the user can change a background color, and you want to log the previous and current colors:

import React, { useState, useEffect, useRef } from "react";

function ColorChanger() {
  const [color, setColor] = useState("red");
  const prevColorRef = useRef(null);

  useEffect(() => {
    if (prevColorRef.current !== null) {
      console.log(`Color changed from ${prevColorRef.current} to ${color}`);
    }
    prevColorRef.current = color; // Update the ref after each render
  }, [color]);

  return (
    <div>
      <p>Current Color: {color}</p>
      <button onClick={() => setColor("blue")}>Set Blue</button>
      <button onClick={() => setColor("green")}>Set Green</button>
    </div>
  );
}

export default ColorChanger;

Key Points to Remember

  • useRef Doesn't Trigger Re-renders: Updating useRef.current doesn’t re-render the component.

  • Works Across Renders: The value of useRef.current persists even when the component re-renders.

  • Use with useEffect: Update the useRef value inside useEffect to ensure it always stores the latest state value after render.