Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@anandarizki/use-undo-redo

anandarizki360MIT1.0.7TypeScript support: included

A hook provides a simple and efficient way to manage undo and redo functionality in your React applications

react, hook, useUndoRedo, undo, redo, state management, history, time travel, debounce, state, react-hooks, history stack, state history, undo-redo, react state, state management library, state management hook, react state management, javascript, typescript

readme

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.

Compatiblity

"react": "^18.2.0"

Demo

https://undoredo.rizki.id

Features

  • Undo and Redo: Effortlessly navigate backward and forward through the state history.
  • Configurable History Capacity: Define the maximum number of state changes to keep in memory.
  • Debounce Support: Optimize performance by controlling the frequency of state history updates.
  • History Management: Access the full history stack, reset the history, or jump to a specific point.
  • Lightweight and Easy to Integrate: Minimal setup required to integrate into existing React components.

Installation

npm i @anandarizki/use-undo-redo

Basic Usage

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

//your state handler
const [state, setState] = useState();

//initialize hooks and pass your state and setState as the argument
const [undo, redo] = useUndoRedo([state, setState]);

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.

Original component

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>
  );
}

Component with useUndoRedo

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>

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

useUndoRedo

useUndoRedo<T>(primaryState: [T, (v: T) => void], options?: Options): Output<T>
  • primaryState: An array containing the state value and the state setter function. This allows the hook to manage the history of this specific state.

  • options:

    • capacity (optional): The maximum number of state changes to keep in history. Default is 10.
    • debounce (optional): The time in milliseconds to debounce history updates. It useful when your state update frequently, ie. when updating state using controlled input. Default is 0 (no debounce).
  • Returns: An array containing:

    • undo: A function to revert to the previous state.
    • redo: A function to move forward to the next state.
    • An object with the following properties:
      • canUndo: A boolean indicating if an undo operation is possible.
      • canRedo: A boolean indicating if a redo operation is possible.
      • reset: A function to clear the history and reset the pointer.
      • history: An array representing the current state history. jumpTo: A function to jump to a specific point in the history by index.

Full usage

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