https://github.com/mutativejs/use-travel
A React hook for state time travel with undo, redo, reset and archive functionalities.
https://github.com/mutativejs/use-travel
immutable mutative react react-hooks redo state-history time-travel undo use-undo
Last synced: about 2 months ago
JSON representation
A React hook for state time travel with undo, redo, reset and archive functionalities.
- Host: GitHub
- URL: https://github.com/mutativejs/use-travel
- Owner: mutativejs
- License: mit
- Created: 2024-03-03T15:05:44.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-02-25T15:55:16.000Z (3 months ago)
- Last Synced: 2025-03-27T03:04:27.772Z (about 2 months ago)
- Topics: immutable, mutative, react, react-hooks, redo, state-history, time-travel, undo, use-undo
- Language: TypeScript
- Homepage:
- Size: 401 KB
- Stars: 81
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# use-travel

[](https://coveralls.io/github/mutativejs/use-travel?branch=main)
[](https://www.npmjs.com/package/use-travel)
A React hook for state time travel with undo, redo, reset and archive functionalities.
### Motivation
`use-travel` is a small and high-performance library for state time travel. It's built on [Mutative](https://github.com/unadlib/mutative) to support mutation updating immutable data. It's designed to be simple and easy to use, and it's also customizable for different use cases.
It's suitable for building any time travel feature in your application.
### Installation
```bash
npm install use-travel mutative
# or
yarn add use-travel mutative
```### Features
- Undo/Redo/Reset/Go/Archive functionalities
- Mutations update immutable data
- Small size for time travel with JSON Patch history
- Customizable history size
- Customizable initial patches
- High performance
- Mark function for custom immutability### Example
- [Basic](https://stackblitz.com/edit/react-xfw3uk?file=src%2FApp.js)
- [Manual Time Travel](https://stackblitz.com/edit/react-3mnzq9?file=src%2FApp.js)### API
You can use `useTravel` to create a time travel state. And it returns a tuple with the current state, the state setter, and the controls. The controls include `back()`, `forward()`, `reset()`, `canBack()`, `canForward()`, `canArchive()`, `getHistory()`, `patches`, `position`, `archive()`, and `go()`.
```jsx
import { useTravel } from 'use-travel';const App = () => {
const [state, setState, controls] = useTravel(0, {
maxHistory: 10,
initialPatches: {
patches: [],
inversePatches: [],
},
});
return (
{state}
setState(state + 1)}>Increment
setState(state - 1)}>Decrement
controls.back()} disabled={!controls.canBack()}>
Undo
controls.forward()}
disabled={!controls.canForward()}
>
Redo
Reset
{controls.getHistory().map((state, index) => (
{state}
))}
{controls.patches.patches.map((patch, index) => (
{JSON.stringify(patch)}
))}
{controls.position}
{
controls.go(1);
}}
>
Go
);
};
```### Parameters
| Parameter | type | description | default |
| ----------------- | ------------- | ------------------------------------- | -------------------------------- |
| `maxHistory` | number | The maximum number of history to keep | 10 |
| `initialPatches` | TravelPatches | The initial patches | {patches: [],inversePatches: []} |
| `initialPosition` | number | The initial position of the state | 0 |
| `autoArchive` | boolean | Auto archive the state | true |### Returns
| Return | type | description |
| --------------------- | ------------------------------ | ---------------------------------------------------------------------- |
| `state` | Value | The current state |
| `setState` | Updater> | The state setter, support mutation update or return immutable data |
| `controls.back` | (amount?: number) => void | Go back to the previous state |
| `controls.forward` | (amount?: number) => void | Go forward to the next state |
| `controls.reset` | () => void | Reset the state to the initial state |
| `controls.canBack` | () => boolean | Check if can go back to the previous state |
| `controls.canForward` | () => boolean | Check if can go forward to the next state |
| `controls.canArchive` | () => boolean | Check if can archive the current state |
| `controls.getHistory` | () => T[] | Get the history of the state |
| `controls.patches` | TravelPatches[] | Get the patches history of the state |
| `controls.position` | number | Get the current position of the state |
| `controls.go` | (nextPosition: number) => void | Go to the specific position of the state |
| `controls.archive` | () => void | Archive the current state(the `autoArchive` options should be `false`) |> `TravelPatches` is the type of patches history, it includes `patches` and `inversePatches`.
> If you want to control the state travel manually, you can set the `autoArchive` option to `false`, and use the `controls.archive` function to archive the state.
> If you want to persist the state, you can use `state`/`controls.patches`/`controls.position` to save the travel history. Then, read the persistent data as `initialState`, `initialPatches`, and `initialPosition` when initializing the state, like this:
```jsx
const [state, setState, controls] = useTravel(initialState, {
initialPatches,
initialPosition,
});
```## License
`use-travel` is [MIT licensed](https://github.com/mutativejs/use-travel/blob/main/LICENSE).