@anandarizki/use-undo-redo

The useUndoRedo hook provides a simple and efficient way to manage undo and redo functionality in your React applications. It helps you maintain a history of state changes, allowing users to seamlessly navigate through different states of your application.

Installation

npm i @anandarizki/use-undo-redo

Usage

//import the hook
import { useUndoRedo } from "@anandarizki/use-undo-redo";

//in react component
const state = useState(0);
const [undo, redo] = useUndoRedo(state);

Integrating into an Existing Component

You don't need to overhaul your existing state management. This hook can be seamlessly integrated into your code with just a single line addition.

import { useState } from "react";

function MyComponent() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <div>
        <button onClick={() => setCount(count - 1)}>-</button>
        {count}
        <button onClick={() => setCount(count + 1)}>+</button>
      </div>
    </div>
  );
}

Add useUndoRedo into your existing component.

import { useState } from "react";
import { useUndoRedo } from "@anandarizki/use-undo-redo";

function MyComponent() {
  const [count, setCount] = useState(0);

  //new line
  const [undo, redo] = useUndoRedo([count, setCount]);

  return (
    <div>
      <div>
        <button onClick={() => setCount(count - 1)}>-</button>
        {count}
        <button onClick={() => setCount(count + 1)}>+</button>
      </div>

      {/* add your undo/redo button */}
      <div>
        <button onClick={undo}>
          Undo
        </button>
        <button onClick={redo}>
          Redo
        </button>
      </div>
    </div>
  );
}

useUndoRedo

const [undo, redo, { canUndo, canRedo, jumpTo, history, pointer, reset }] =
  useUndoRedo([state, setState], {
    debounce: 500,
    capacity: 20,
  });

Types

useUndoRedo<T>(primaryState: [T, (v: T) => void], options?: Options): Output<T>
type Options = {
  capacity?: number; // the limit number of history list, default = 10
  debounce?: number; // delay time in milliseconds from latest activity before a state change added into the history list
};

type StateHistory<T> = {
  value: T;
  timestamp: Date;
};

type Output<T> = [
  () => void, // function to call undo
  () => void, // function to call redo
  {
    canUndo: boolean; // the status of undo availability
    canRedo: boolean; // the status of redo availability
    reset: () => void; // function to clear the history
    history: StateHistory<T>[]; // list of history
    jumpTo: (pointer: number) => void; // function to jump into a history
    pointer: number; // current active pointer
  }
];

Example

All components in the examples use shadcn/ui. This is just for demonstration purposes, and you are free to use any UI framework

UndoRedo.tsx

This is a generic undo/redo button component that will be used across all examples.

Basic

Basic implementation

0

Disabled Button

Pass the canUndo and canRedo values to the buttons, allowing you to disable them based on availability.

0

Debounce

This option is useful for handling frequent state updates, such as those in controlled input components.

0

Full Usage

Current value: