Coder Social home page Coder Social logo

ptzagk / redux-machine-immutable Goto Github PK

View Code? Open in Web Editor NEW

This project forked from mheiber/redux-machine-immutable

0.0 0.0 0.0 26 KB

A tiny lib for creating state machines as swappable Redux reducers that operate on Immutable JS maps

JavaScript 100.00%

redux-machine-immutable's Introduction

redux-machine

redux-machine

A tiny lib (16 lines) for creating state machines as swappable Redux reducers

This is the version of this library to use when your Redux store state is an Immutable JS Map. See also the non-immutable-js version of redux-machine.

redux-machine enables you to create reducers that can transition between different "statuses." These are likes states in a finite state machine. The goal is for redux-machine to support complex workflows simply while keeping all state in the redux store. Keeping all state in the store is good because:

  • redux-machine works with time-travel debugging. Time-travel debugging was the main motivation for building redux itself.
  • Debugging is easy because information is in one place (the store).
  • Statuses such are queryable by the user interface. This is helpful if you want to show things to the user such as loading spinners to indicate status

Install

npm install redux-machine --save

redux-machine internally uses Object.assign, which is an ES2015 feature. If you need to support older browsers, you can use a polyfill such as core-js.

How to Use

This is the entire API for redux-machine:

// entire API, no middleware required
import { createMachine } = from './index.js'

const fetchUsersReducer = createMachine({
    'INIT': initReducer,
    'IN_PROGRESS': inProgressReducer
})

The reducer returned by createMachine will act like initReducer when its status is INIT and will act like inProgressReducer when the status is IN_PROGRESS. If the store's state.status is undefined, the reducer for INIT is used (so it's a good idea to provide a reducer for the INIT status).

initReducer and inProgressReducer can do status transitions by setting state.status:

const initReducer = (state = {error: null, users: []}, action) => {
    switch (action.type) {
    case 'FETCH_USERS':
        return state
                .set('error', null)
                .set('status', 'IN_PROGRESS')
    })
    default:
        return state
    }
}

const inProgressReducer = (state = {}, action) => {
    switch (action.type) {
    case 'FETCH_USERS_RESPONSE':
        return state.withMutations(map => {
            return map
                .set('error', null)
                .set('users', action.payload.users)
                .set('status', 'INIT')
        })
    case 'FETCH_USERS_FAIL':
        return state
                .set('error', action.payload.error)
                .set('status', 'INIT')
        return state
                .set('error', action.payload.error)
                .set('status', 'INIT')
    default:
        return state
    }
}

The example above defines the following state machine:

status machine for the api-calling example

In words:

  • When the status is INIT and the action type is FETCH_USERS, the machine transitions to IN_PROGRESS status.
  • When the status is IN_PROGRESS and the action type is FETCH_USERS_RESPONSE or FETCH_USERS_FAIL, the machine transitions to the INIT (initial) status.

Making Finite State Machine Reducers without a Library

You don't need redux-machine, since you can accomplish almost the same thing as in the example above by defining fetchUsersReducer as follows:

const fetchUsersReducer = (state, action) => {
    switch (state.get(status)) {
    case 'INIT':
        return initReducer(state, action)
    case 'IN_PROGRESS':
        return inProgressReducer(state, action)
    default:
        return initReducer(state, action)
    }
}

The (marginal) advantages of using redux-machine over just using the FSM pattern is that you can more clearly express intent and write slightly less code.

Examples

Cancellable Counter

Shopping Cart

These examples use the non-immutable-js version of redux-machine.

redux-machine-immutable's People

Contributors

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