npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@custom-react-hooks/use-previous

v1.0.0

Published

A React hook that stores the previous value of a state or prop

Downloads

267

Readme

usePrevious Hook

The usePrevious hook is a simple yet powerful utility that stores the previous value of a state or prop. It's particularly useful for comparing current and previous values in effects, implementing animations based on value changes, or tracking state transitions.

Features

  • Simple Value Tracking: Stores the previous value of any data type.
  • Type Safe: Full TypeScript support with generic typing.
  • Memory Efficient: Uses a single ref to store the previous value.
  • Universal Compatibility: Works with any data type (primitives, objects, arrays).
  • SSR Safe: No side effects during server-side rendering.

Installation

Installing Only Current Hooks

npm install @custom-react-hooks/use-previous

or

yarn add @custom-react-hooks/use-previous

Installing All Hooks

npm install @custom-react-hooks/all

or

yarn add @custom-react-hooks/all

Usage

Basic Usage

import React, { useState } from 'react';
import { usePrevious } from '@custom-react-hooks/use-previous';

const CounterComponent = () => {
  const [count, setCount] = useState(0);
  const previousCount = usePrevious(count);

  return (
    <div>
      <h2>Counter: {count}</h2>
      <p>Previous count: {previousCount ?? 'None'}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <button onClick={() => setCount(count - 1)}>Decrement</button>
    </div>
  );
};

export default CounterComponent;

Comparing Values in Effects

import React, { useState, useEffect } from 'react';
import { usePrevious } from '@custom-react-hooks/use-previous';

const UserProfile = ({ userId }: { userId: string }) => {
  const [user, setUser] = useState(null);
  const previousUserId = usePrevious(userId);

  useEffect(() => {
    // Only fetch if userId actually changed
    if (previousUserId !== userId) {
      fetchUser(userId).then(setUser);
    }
  }, [userId, previousUserId]);

  return <div>{user ? user.name : 'Loading...'}</div>;
};

Animation Based on Value Changes

import React, { useState } from 'react';
import { usePrevious } from '@custom-react-hooks/use-previous';

const AnimatedValue = () => {
  const [value, setValue] = useState(0);
  const previousValue = usePrevious(value);
  
  const isIncreasing = previousValue !== undefined && value > previousValue;
  const isDecreasing = previousValue !== undefined && value < previousValue;

  return (
    <div>
      <div 
        className={`value ${isIncreasing ? 'increasing' : ''} ${isDecreasing ? 'decreasing' : ''}`}
      >
        {value}
      </div>
      <button onClick={() => setValue(v => v + 1)}>+</button>
      <button onClick={() => setValue(v => v - 1)}>-</button>
    </div>
  );
};

Working with Objects

import React, { useState } from 'react';
import { usePrevious } from '@custom-react-hooks/use-previous';

const FormComponent = () => {
  const [formData, setFormData] = useState({ name: '', email: '' });
  const previousFormData = usePrevious(formData);

  const hasChanged = previousFormData && 
    JSON.stringify(previousFormData) !== JSON.stringify(formData);

  return (
    <div>
      <input
        value={formData.name}
        onChange={(e) => setFormData(prev => ({ ...prev, name: e.target.value }))}
        placeholder="Name"
      />
      <input
        value={formData.email}
        onChange={(e) => setFormData(prev => ({ ...prev, email: e.target.value }))}
        placeholder="Email"
      />
      {hasChanged && <p>Form has been modified</p>}
    </div>
  );
};

API Reference

Parameters

  • value (T): The current value to track. Can be of any type.

Returns

  • T | undefined: The previous value. Returns undefined on the first render.

Use Cases

  • Value Comparison: Compare current and previous values in effects or render logic.
  • Animation Triggers: Trigger animations based on value changes.
  • Optimization: Prevent unnecessary API calls or expensive operations when values haven't changed.
  • State Transitions: Track state transitions for debugging or analytics.
  • Form Validation: Implement validation that depends on previous form states.
  • Undo Functionality: Implement simple undo functionality by storing previous states.

TypeScript Support

The hook is fully typed and will infer the type from the value you pass:

const previousString = usePrevious('hello'); // string | undefined
const previousNumber = usePrevious(42); // number | undefined
const previousObject = usePrevious({ key: 'value' }); // { key: string } | undefined

Performance Considerations

  • The hook uses a single useRef to store the previous value, making it very lightweight.
  • It only updates the ref after the component has rendered, ensuring the previous value is always from the last render cycle.
  • No unnecessary re-renders are triggered by this hook.

Contributing

Contributions to enhance usePrevious are welcome. Feel free to submit issues or pull requests to the repository.

License

MIT License - see the LICENSE file for details.