Use Ref Previous Value
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 auseRefvalue 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
.currentproperty of auseRefobject 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
useReffor Storage:prevCountRefis initialized usinguseRef(null)to hold the previous value ofcount.
Update in
useEffect:- The
useEffectruns after every render, updating theprevCountRef.currentwith the latest value ofcount.
- The
Access Previous Value:
- The previous value is accessible via
prevCountRef.currentbefore it gets updated in the next render.
- The previous value is accessible via
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
useRefDoesn't Trigger Re-renders: UpdatinguseRef.currentdoesn’t re-render the component.Works Across Renders: The value of
useRef.currentpersists even when the component re-renders.Use with
useEffect: Update theuseRefvalue insideuseEffectto ensure it always stores the latest state value after render.