@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
Disabled Button
Pass the canUndo and canRedo values to the buttons, allowing you to disable them based on availability.
Debounce
This option is useful for handling frequent state updates, such as those in controlled input components.