use-track-history
Version:
React hook to track state history with undo/redo functionality
165 lines (119 loc) • 4.55 kB
Markdown
[](https://www.npmjs.com/package/use-track-history)
[](https://bundlephobia.com/package/use-track-history)
[](https://opensource.org/licenses/MIT)
A lightweight React hook for state history tracking with undo/redo capabilities.
- 🪶 **Lightweight**: < 1KB minzipped, zero dependencies
- 🧠 **Type-safe**: Written in TypeScript with full type support
- 🧩 **Flexible**: Works with any data type (strings, objects, arrays)
- ⚡ **Optimized**: Uses React's built-in performance optimization hooks
## Installation
```bash
npm install use-track-history # or: yarn add use-track-history
```
## Quick Start
```tsx
import { useTrackHistory } from "use-track-history";
function TextEditor() {
const { value, update, reset, history } = useTrackHistory("Initial text");
return (
<div>
<textarea value={value} onChange={(e) => update(e.target.value)} />
<div className="toolbar">
<button onClick={history.undo} disabled={!history.canUndo}>
Undo
</button>
<button onClick={history.redo} disabled={!history.canRedo}>
Redo
</button>
<button onClick={() => reset("Initial text")}>Reset</button>
</div>
</div>
);
}
```
Creates a history-tracked state.
| Parameter | Description |
| -------------- | --------------------------------- |
| `defaultValue` | Initial value to store in history |
| `options` | Optional configuration object |
| Option | Type | Description |
| ---------------- | ------ | ------------------------------------------------------------------------------------- |
| `maxHistorySize` | number | Maximum number of history entries to keep. When exceeded, oldest entries are removed. |
| Property | Description |
| --------- | ------------------------------------------------- |
| `value` | Current value in the history |
| `update` | Updates the value and adds it to history |
| `reset` | Clears history and sets a new initial value |
| `history` | Contains history control functions and properties |
| Property | Type | Description |
| --------- | -------- | ------------------------------- |
| `undo` | function | Move back to previous state |
| `redo` | function | Move forward to next state |
| `canUndo` | boolean | Check if undo is available |
| `canRedo` | boolean | Check if redo is available |
| `length` | number | Total number of history entries |
In Typescript, we can type our history object:
```tsx
import { useTrackHistory } from "use-track-history";
type Profile = {
name: string;
age: number;
};
function MyComponent() {
const { value, update, history } = useTrackHistory<Profile>({
name: "Bob",
age: 32,
});
// ...
}
```
You can use the excellent [`react-hotkeys-hook`](https://www.npmjs.com/package/react-hotkeys-hook) library
to add <kbd>Cmd+Z</kbd> and <kbd>Cmd+Shift+Z</kbd> keyboard shortcuts:
```tsx
import { useTrackHistory } from "use-track-history";
function MyComponent() {
const { value, update, history } = useTrackHistory("initial value");
useHotkeys("mod+z", history.undo, {
enabled: history.canUndo,
preventDefault: true,
});
useHotkeys("mod+shift+z", history.redo, {
// or ctrl+y on Windows
enabled: history.canRedo,
preventDefault: true,
});
// ...
}
```
To limit memory usage, you might want to limit the history size:
```tsx
import { useTrackHistory } from "use-track-history";
function MyComponent() {
const { value, update, reset, history } = useTrackHistory("", {
maxHistorySize: 30,
});
// ...
}
```
<br /><br />
---
<div align="center">
<b>
<a href="https://includable.com/consultancy?utm_source=use-track-history">Get professional support for this package →</a>
</b>
<br>
<sub>
Custom consulting sessions available for implementation support or feature development.
</sub>
</div>