Home > @cascadiacollections/fluentui-compat > usePrevious
usePrevious() function
Hook to track and return the previous value of a prop or state.
This hook captures and returns the value from the previous render, which is useful for: - **Comparison logic**: Detecting when a value has changed - **Animation triggers**: Starting animations when values change - **Effect optimization**: Avoiding unnecessary effects when values haven't changed - **Debugging**: Tracking value changes over time
**Implementation Details**: - Uses useEffect to update the previous value after render - On first render, returns undefined since there's no previous value - Works with any type including primitives, objects, and functions - Does not deep-compare objects - only tracks reference changes
Signature:
export declare function usePrevious<T>(value: T): T | undefined;
Parameters
|
Parameter |
Type |
Description |
|---|---|---|
|
value |
T |
The current value to track |
Returns:
T | undefined
The value from the previous render, or undefined on first render
Example 1
// Detect when a prop changes
function UserProfile({ userId }: { userId: string }) {
const previousUserId = usePrevious(userId);
useEffect(() => {
if (previousUserId !== undefined && previousUserId !== userId) {
console.log('User changed from', previousUserId, 'to', userId);
// Fetch new user data
}
}, [userId, previousUserId]);
return <div>User: {userId}</div>;
}
Example 2
// Track count changes for animations
function Counter() {
const [count, setCount] = useState(0);
const previousCount = usePrevious(count);
const isIncreasing = previousCount !== undefined && count > previousCount;
const isDecreasing = previousCount !== undefined && count < previousCount;
return (
<div>
<h2 className={isIncreasing ? 'animate-up' : isDecreasing ? 'animate-down' : ''}>
{count}
</h2>
<button onClick={() => setCount(c => c + 1)}>Increment</button>
<button onClick={() => setCount(c => c - 1)}>Decrement</button>
</div>
);
}
Example 3
// Optimize effects by comparing previous and current values
function DataFetcher({ filters }: { filters: FilterObject }) {
const previousFilters = usePrevious(filters);
const [data, setData] = useState(null);
useEffect(() => {
// Only fetch if filters actually changed (by reference)
if (previousFilters !== filters) {
fetchData(filters).then(setData);
}
}, [filters, previousFilters]);
return <DataDisplay data={data} />;
}
Example 4
// Handle both first render and value changes
function SearchResults({ query }: { query: string }) {
const previousQuery = usePrevious(query);
if (previousQuery === undefined) {
return <div>Enter a search query</div>;
}
if (previousQuery !== query) {
return <div>Searching for "{query}"...</div>;
}
return <div>Results for "{query}"</div>;
}
Example 5
// Track object reference changes
function ComponentWithConfig({ config }: { config: Config }) {
const previousConfig = usePrevious(config);
useEffect(() => {
// This will only run when config reference changes
if (previousConfig !== config) {
console.log('Config reference changed');
// Re-initialize based on new config
}
}, [config, previousConfig]);
return <div>Component</div>;
}