GithubHelp home page GithubHelp logo

gaearon / redux-optimist Goto Github PK

View Code? Open in Web Editor NEW

This project forked from forbeslindesay/redux-optimist

4.0 2.0 2.0 12 KB

Optimistically apply actions that can be later commited or reverted.

License: MIT License

JavaScript 100.00%

redux-optimist's Introduction

redux-optimist

Optimistically apply actions that can be later commited or reverted.

Build Status Dependency Status NPM version

Installation

npm install redux-optimist

Usage

Step 1: Wrap your top level reducer in redux-optimist

reducers/todos.js

export default function todos(state = [], action) {
  switch (action.type) {
  case 'ADD_TODO':
    return state.concat([action.text]);
  default:
    return state;
  }
}

reducers/status.js

export default function status(state = {writing: false, error: null}, action) {
  switch (action.type) {
  case 'ADD_TODO':
    return {writing: true, error: null};
  case 'ADD_TODO_COMPLETE':
    return {writing: false, error: null};
  case 'ADD_TODO_FAILED':
    return {writing: false, error: action.error};
  default:
    return state;
  }
}

reducers/index.js

import optimist from 'redux-optimist';
import { combineReducers } from 'redux';
import todos from './todos';
import status from './status';

export default optimist(combineReducers({
  todos,
  status
}));

As long as your top-level reducer returns a plain object, you can use optimist. You don't have to use Redux.combineReducers.

Step 2: Mark your optimistic actions with the optimist key

middleware/api.js

import {BEGIN, COMMIT, REVERT} from 'redux-optimist';
import request from 'then-request';

let nextTransactionID = 0;
export default function (store) {
  return next => action => {
    if (action.type !== 'ADD_TODO') {
      return next(action);
    }
    let transactionID = nextTransactionID++;
    next({
      type: 'ADD_TODO',
      text: action.text,
      optimist: {type: BEGIN, id: transactionID}
    });
    request('POST', '/add_todo', {text: action.text}).getBody().done(
      res => next({
        type: 'ADD_TODO_COMPLETE',
        text: action.text,
        response: res,
        optimist: {type: COMMIT, id: transactionID}
      }),
      err => next({
        type: 'ADD_TODO_FAILED',
        text: action.text,
        error: err,
        optimist: {type: REVERT, id: transactionID}
      })
    );
  }
};

Note how we always follow up by either COMMITing the transaction or REVERTing it. If you do neither, you will get a memory leak. Also note that we use a serialisable transactionID such as a number. These should always be unique accross the entire system.

Step 3:

Using this, we can safely fire off ADD_TODO actions in the knowledge that the UI will update optimisticly, but will revert if the write to the server fails.

App.js

import { createStore, applyMiddleware } from 'redux';
import api from './middleware/api';
import reducer from './reducers';

let store = applyMiddleware(api)(createStore)(reducer);
console.log(store.getState());
// {
//   optimist: {...},
//   todos: [],
//   status: {writing: false, error: null}
// }

store.dispatch({
  type: 'ADD_TODO',
  text: 'Use Redux'
});
console.log(store.getState());
// {
//   optimist: {...},
//   todos: ['Use Redux'],
//   status: {writing: true, error: null}
// }

// You can apply other actions here and their updates won't get lost
// even if the original ADD_TODO action gets reverted.

// Some time later...
console.log(store.getState());
// either
// {
//   optimist: {...},
//   todos: ['Use Redux'],
//   status: {writing: false, error: null}
// }
// or
// {
//   optimist: {...},
//   todos: [],
//   status: {writing: false, error: Error}
// }

License

MIT

redux-optimist's People

Contributors

forbeslindesay avatar frankleonrose avatar pschlette avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  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.