GithubHelp home page GithubHelp logo

jasonslyvia / redux-undo Goto Github PK

View Code? Open in Web Editor NEW

This project forked from omnidan/redux-undo

0.0 0.0 0.0 66 KB

:recycle: simple undo/redo functionality for redux state containers

License: MIT License

JavaScript 100.00%

redux-undo's Introduction

redux undo/redo

NPM version (>=0.4) NPM Downloads Build Status Dependencies js-standard-style https://paypal.me/DanielBugl/10 https://gratipay.com/~omnidan/

simple undo/redo functionality for redux state containers

https://i.imgur.com/M2KR4uo.gif

Protip: You can use the redux-undo-boilerplate to quickly get started with redux-undo.

Switching from 0.x to 1.0 (beta): Make sure to update your programs to the latest History API.

Installation

npm install --save redux-undo

Or you can install the beta:

npm install --save redux-undo@beta

API

import undoable from 'redux-undo';
undoable(reducer)
undoable(reducer, config)

Making your reducers undoable

redux-undo is a reducer enhancer, it provides the undoable function, which takes an existing reducer and a configuration object and enhances your existing reducer with undo functionality.

Note: If you were accessing state.counter before, you have to access state.counter.present after wrapping your reducer with undoable.

To install, firstly import redux-undo:

// Redux utility functions
import { combineReducers } from 'redux';
// redux-undo higher-order reducer
import undoable from 'redux-undo';

Then, add undoable to your reducer(s) like this:

combineReducers({
  counter: undoable(counter)
})

A configuration can be passed like this:

combineReducers({
  counter: undoable(counter, {
    limit: 10 // set a limit for the history
  })
})

History API

Wrapping your reducer with undoable makes the state look like this:

{
  past: [...pastStatesHere...],
  present: {...currentStateHere...},
  future: [...futureStatesHere...]
}

Now you can get your current state like this: state.present

And you can access all past states (e.g. to show a history) like this: state.past

Undo/Redo Actions

Firstly, import the undo/redo action creators:

import { ActionCreators } from 'redux-undo';

Then, you can use store.dispatch() and the undo/redo action creators to perform undo/redo operations on your state:

store.dispatch(ActionCreators.undo()) // undo the last action
store.dispatch(ActionCreators.redo()) // redo the last action

store.dispatch(ActionCreators.jumpToPast(index)) // jump to requested index in the past[] array
store.dispatch(ActionCreators.jumpToFuture(index)) // jump to requested index in the future[] array

Configuration

A configuration object can be passed to undoable() like this (values shown are default values):

undoable(reducer, {
  limit: false, // set to a number to turn on a limit for the history

  filter: () => true, // see `Filtering Actions` section

  undoType: ActionTypes.UNDO, // define a custom action type for this undo action
  redoType: ActionTypes.REDO, // define a custom action type for this redo action

  jumpToPastType: ActionTypes.JUMP_TO_PAST, // define custom action type for this jumpToPast action
  jumpToFutureType: ActionTypes.JUMP_TO_FUTURE, // define custom action type for this jumpToFuture action

  initialState: undefined, // initial state (e.g. for loading)
  initTypes: ['@@redux/INIT', '@@INIT'] // history will be (re)set upon init action type
  initialHistory: { // initial history (e.g. for loading)
    past: [],
    present: config.initialState,
    future: []
  },

  debug: false, // set to `true` to turn on debugging
})

Note: If you want to use just the initTypes functionality, but not import the whole redux-undo library, use redux-recycle!

Filtering Actions

If you don't want to include every action in the undo/redo history, you can pass a function to undoable like this:

undoable(reducer, {
  filter: function filterActions(action, currentState, previousState) {
    return action.type === SOME_ACTION; // only add to history if action is SOME_ACTION
  }
})

// or you could do...

undoable(reducer, {
  filter: function filterState(action, currentState, previousState) {
    return currentState !== previousState; // only add to history if state changed
  }
})

Or you can use the distinctState, includeAction and excludeAction helpers, which should be imported like this:

import undoable, { distinctState, includeAction, excludeAction } from 'redux-undo';

Now you can use the helper, which is pretty simple:

undoable(reducer, { filter: includeAction(SOME_ACTION) })
undoable(reducer, { filter: excludeAction(SOME_ACTION) })

// or you could do...

undoable(reducer, { filter: distinctState() })

... they even support Arrays:

undoable(reducer, { filter: includeAction([SOME_ACTION, SOME_OTHER_ACTION]) })
undoable(reducer, { filter: excludeAction([SOME_ACTION, SOME_OTHER_ACTION]) })

Ignoring Actions

When implementing a filter function, it only prevents the old state from being stored in the history. filter does not prevent the present state from being updated.

If you want to ignore an action completely, as in, not even update the present state, you can make use of redux-ignore.

It can be used like this:

import { ignoreActions } from 'redux-ignore'

ignoreActions(
  undoable(reducer),
  [IGNORED_ACTION, ANOTHER_IGNORED_ACTION]
)

// or define your own function:

ignoreActions(
  undoable(reducer),
  (action) => action.type === SOME_ACTION // only add to history if action is SOME_ACTION
)

What is this magic? How does it work?

Have a read of the Implementing Undo History recipe in the Redux documents, which explains in detail how redux-undo works.

License

MIT, see LICENSE.md for more information.

redux-undo's People

Contributors

omnidan avatar danielkcz avatar pl12133 avatar adrianp avatar leomelin avatar neojski avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.