Back to Code Bytes
2 min read
usePrevious

Description

This hook tracks the previous value of a state or prop.

🍎 Code Byte

import { useRef, useEffect } from 'react';

export const usePrevious = <T, _>(value: T) => {
  const ref = useRef<T | null>(null);

  useEffect(() => {
    ref.current = value;
  }, [value]);

  return ref.current;
};

Arguments

ArgumentsTypeDefaultRequiredDescription
valueany-The currrent value to be tracked and stored as the previous value.

Returns

ReturnsTypeDescription
valueanyThe previous value of the tracked state. On initial render it will return null.

Usage

const Component = () => {
  const [count, setCount] = useState(0);
  const prevCount = usePrevious(count);

  return (
    <div>
      <h1>
        Now: {count}, before: {prevCount}
      </h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

Tests

import { renderHook } from '@testing-library/react-hooks';
import { usePrevious } from './usePrevious.hook';

describe('usePrevious()', () => {
  it('should return null for the initial render', () => {
    const { result } = renderHook(() => usePrevious(0));

    expect(result.current).toBeNull();
  });

  it('should return the previous value after a re-render', () => {
    const { result, rerender } = renderHook(({ value }) => usePrevious(value), {
      initialProps: { value: 0 }
    });

    // Initial render
    expect(result.current).toBeNull();

    // Update with new value
    rerender({ value: 1 });
    expect(result.current).toEqual(0);

    // Update with another new value
    rerender({ value: 2 });
    expect(result.current).toEqual(1);
  });
});