• Stars
    star
    393
  • Rank 109,518 (Top 3 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created about 6 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

React Hooks to implement Undo and Redo functionality

♻️ use-undo

undo/redo functionality with React Hooks.

screensho

Installation

yarn add use-undo

Usage

Edit use-undo-demo

import React from 'react';
import ReactDOM from 'react-dom';
import useUndo from 'use-undo';

const App = () => {
  const [
    countState,
    {
      set: setCount,
      reset: resetCount,
      undo: undoCount,
      redo: redoCount,
      canUndo,
      canRedo,
    },
  ] = useUndo(0);
  const { present: presentCount } = countState;

  return (
    <div>
      <p>You clicked {presentCount} times</p>
      <button key="increment" onClick={() => setCount(presentCount + 1)}>
        +
      </button>
      <button key="decrement" onClick={() => setCount(presentCount - 1)}>
        -
      </button>
      <button key="undo" onClick={undoCount} disabled={!canUndo}>
        undo
      </button>
      <button key="redo" onClick={redoCount} disabled={!canRedo}>
        redo
      </button>
      <button key="reset" onClick={() => resetCount(0)}>
        reset to 0
      </button>
    </div>
  );
};

Manual Checkpoints

Manual checkpoints are helpful also when you want manual control over checkpoints. For example it is more helpful when you want to handle input type html tag where value needs to be handled alongside the undo and redo functionality should be handled over some conditions.

import React from 'react';
import ReactDOM from 'react-dom';
import useUndo from 'use-undo';

const App = () => {
  const [
    countState,
    {
      set: setCount,
      reset: resetCount,
      undo: undoCount,
      redo: redoCount,
      canUndo,
      canRedo,
    },
  ] = useUndo(0, { useCheckpoints: true });
  const { present: presentCount } = countState;

  return (
    <div>
      <p>You clicked {presentCount} times</p>
      <button key="increment" onClick={() => setCount(presentCount + 1, true)}>
        WithCheckpoint+
      </button>
      <button key="decrement" onClick={() => setCount(presentCount - 1, true)}>
        WithCheckpoint-
      </button>
      <button key="increment" onClick={() => setCount(presentCount + 1)}>
        NoCheckpoint+
      </button>
      <button key="decrement" onClick={() => setCount(presentCount - 1)}>
        NoCheckpoint-
      </button>
      <button key="undo" onClick={undoCount} disabled={!canUndo}>
        undo
      </button>
      <button key="redo" onClick={redoCount} disabled={!canRedo}>
        redo
      </button>
      <button key="reset" onClick={() => resetCount(0)}>
        reset to 0
      </button>
    </div>
  );
};

API

useUndo

const [state, actions] = useUndo(initialState);

state

Type: Object
Key Type Description
past Array The undo stack.
present Any The present state.
future Array The redo stack.

actions

Type: Object
Key Type Description
set function Assign a new value to present.
reset function Clear past array and future array. Assign a new value to present.
undo function See handling-undo.
redo function See handling-redo.
canUndo boolean Check whether state.undo.length is 0.
canRedo boolean Check whether state.redo.length is 0.

How does it work?

Refer to Redux Implementing Undo History, use-undo implements the same concect with useReducer.
The state structure looks like:

{
  past: Array<T>,
  present: <T>,
  future: Array<T>
}

It stores all states we need. To operate on this state, there are three functions in actions (set, undo and redo) that dispatch defined types and necessary value.

Related repo

License

MIT © homerchen19

More Repositories

1

nba-go

🏀 💻 The finest NBA CLI.
JavaScript
3,709
star
2

github-file-icons

🌈 🗂 A browser extension which gives different filetypes different icons to GitHub, GitLab, gitea and gogs.
TypeScript
1,426
star
3

bootstrap-webpack-jquery-boilerplate

Bootstrap 4 + Webpack 4 + jQuery = 😋
HTML
245
star
4

nba-bar

🏀 🖥️ Check NBA in your menubar.
JavaScript
86
star
5

react-water-wave

💧React.js jquery.ripples integration component.
TypeScript
66
star
6

nba-color

🏀 🎨 Get all NBA team's color.
JavaScript
51
star
7

github-uploader

🔗 🖥 Upload attachments to GitHub in CLI. A simple and tricky way to get public URL to your files.
JavaScript
30
star
8

react-linear-gradient-button

React linear gradient button component.
JavaScript
14
star
9

leetcode-30days

Write 30 LeetCode in 30 days
JavaScript
12
star
10

laravel-react-redux-boilerplate

A simple boilerplate for React and Redux with Laravel as API server.
PHP
10
star
11

github-unfold-news

↕️ Auto unfold news on GitHub dashboard
JavaScript
10
star
12

infinite-array

∞ Infinite array index using ES2015 Proxy
TypeScript
9
star
13

take-a-break

A simple CLI tool for setting an alarm.
TypeScript
7
star
14

react-props-filter

🥅 Filter miscellaneous props and get props precisely.
JavaScript
4
star
15

react-unstated-todomvc

TodoMVC app in Unstated and React
JavaScript
3
star
16

firefox-av-history-killer

🔞 A Firefox WebExtension which deletes AV browsing history automatically.
JavaScript
3
star
17

vue-vuex-2048

2048 Game with Vue.js-2.0 and Vuex
JavaScript
3
star
18

xxhomey19.github.io

My portfolio web
HTML
2
star
19

simple-lottery-smart-contract

JavaScript
2
star
20

free-tram-zone

Am I in Melbourne's Free Tram Zone?
TypeScript
2
star
21

RollingCat

JavaScript
2
star
22

toc_hw3

Parsing json in Python
Python
1
star