
How to get previous value in useEffect in React
React functional components do not expose previous values directly within useEffect. To compare current and prior values, developers should persist values between renders using useRef. This approach enables precise change detection, efficient side-effect control, and predictable component behavior.
In React functional components, it is often necessary to compare the current value of a state variable or prop with its previous value. Such comparisons are useful for detecting changes, controlling side effects, preventing redundant operations, or triggering transitions.
React does not provide previous values automatically. Each render produces a new snapshot of component state and props, and useEffect executes using values from the most recent render. Therefore, previous values must be stored explicitly when they are needed.
Conceptual Background
When a component re-renders, React re-executes the component function and creates a new render scope. Values from earlier renders are not retained unless they are stored in a persistent container.
The useRef hook provides persistence across renders. Its .current property survives re-renders and can be updated without triggering additional renders.
Using useRef to Track the Previous Value
The recommended approach is to store the current value in a ref after each render. During the next render cycle, the ref still contains the previous value.
import { useEffect, useRef, useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
const previousCountRef = useRef();
useEffect(() => {
previousCountRef.current = count;
}, [count]);
const previousCount = previousCountRef.current;
return (
<div>
<p>Current: {count}</p>
<p>Previous: {previousCount}</p>
<button onClick={() => setCount((c) => c + 1)}>Increase</button>
</div>
);
}How the Code Works
useRefcreates a persistent container.After rendering,
useEffectupdates the ref with the current value.On the next render, the ref still holds the value from the previous render.
The component can safely compare current and previous values.
This method avoids unnecessary re-renders and maintains predictable behavior.
Important Considerations
Initial render behavior
On the first render, the previous value is undefined because no earlier render exists.
Avoid storing previous values in state
Using state for this purpose introduces unnecessary renders and may create update loops.
Update the ref inside useEffect
Updating the ref during rendering would overwrite the previous value before it can be compared.
Practical Use Cases
Tracking previous values is useful when:
determining whether a value increased or decreased
executing logic only when specific changes occur
triggering animations based on value transitions
optimizing performance through value comparison
logging changes for analytics or debugging