Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bradleyboy/use-history-reducer
Experimental immer-based reducer with undo/redo, checkpoints, and forking.
https://github.com/bradleyboy/use-history-reducer
history immer react reducer undo-redo
Last synced: about 2 months ago
JSON representation
Experimental immer-based reducer with undo/redo, checkpoints, and forking.
- Host: GitHub
- URL: https://github.com/bradleyboy/use-history-reducer
- Owner: bradleyboy
- License: mit
- Created: 2019-10-06T02:20:01.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2022-02-12T15:10:34.000Z (almost 3 years ago)
- Last Synced: 2024-10-12T05:42:33.655Z (3 months ago)
- Topics: history, immer, react, reducer, undo-redo
- Language: JavaScript
- Homepage:
- Size: 103 KB
- Stars: 5
- Watchers: 3
- Forks: 0
- Open Issues: 10
-
Metadata Files:
- Readme: Readme.md
- License: LICENSE
Awesome Lists containing this project
README
# useHistoryReducer
This experimental hook provides a light wrapper over `useReducer` which provides undo/redo, forking, and checkpoints. It's built on top of [Immer](https://immerjs.github.io/immer/docs/introduction), so you also get the added benefits it provides.
## Basic example
```js
import React from "react";
import useHistoryReducer from "use-history-reducer";function reducer(state, action) {
if (action.type === "increment") {
state.count += 1;
}
}function App() {
const [state, changes, dispatch] = useHistoryReducer(reducer, { count: 1 });return (
{state.count}
dispatch({ type: "increment" })}>++
changes.undo()}
>
Undo
changes.redo()}
>
Redo
);
}
```## Forking
Forking allows you to break off from the main set of changes temporarily, and either commit all the changes that happen during the fork at once (and in one changeset), or revert them altogether. One use case for this is an input that may change the state many times, and you want only the final value to be recorded.
```js
import React from "react";
import useHistoryReducer from "use-history-reducer";function reducer(state, action) {
if (action.type === "SET_COUNT") {
state.count = action.payload;
}
}function App() {
const [state, changes, dispatch] = useHistoryReducer(reducer, { count: 1 });return (
{state.count}
changes.fork()}
onMouseUp={() => changes.commit()}
onChange={e => dispatch({ type: "SET_COUNT", payload: e.target.value })}
/>
changes.undo()}
>
Undo
changes.redo()}
>
Redo
);
}
```## Checkpoints
By using checkpoints, you can get the the changes made since the last checkpoint. This makes it easy to track unsaved changes you haven't sent to your backend or whatever persistence layer you are using.
```js
import React from "react";
import useHistoryReducer from "use-history-reducer";function reducer(state, action) {
if (action.type === "increment") {
state.count += 1;
}
}function App() {
const [state, changes, dispatch] = useHistoryReducer(reducer, { count: 1 });return (
{state.count}
dispatch({ type: "increment" })}>++
{
const changes = changes.checkpoint();
// do something with the patches.
}}
>
Save
);
}
```