- Notifications
You must be signed in to change notification settings - Fork2
mheiber/redux-machine-immutable
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
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 anImmutable JSMap. See also thenon-immutable-js version of redux-machine.
redux-machine enables you to createreducers that can transition between different "statuses." These are likes states in afinite 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 mainmotivation 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
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 ascore-js.
This is the entire API for redux-machine:
// entire API, no middleware requiredimport{createMachine}=from'./index.js'constfetchUsersReducer=createMachine({'INIT':initReducer,'IN_PROGRESS':inProgressReducer})
The reducer returned bycreateMachine will act likeinitReducer when its status isINIT and will act likeinProgressReducer when the status isIN_PROGRESS. If the store'sstate.status is undefined, the reducer forINIT is used (so it's a good idea to provide a reducer for theINIT status).
initReducer andinProgressReducer can do status transitions by settingstate.status:
constinitReducer=(state={error:null,users:[]},action)=>{switch(action.type){case'FETCH_USERS':returnstate.set('error',null).set('status','IN_PROGRESS')})default:returnstate}}constinProgressReducer=(state={},action)=>{switch(action.type){case'FETCH_USERS_RESPONSE':returnstate.withMutations(map=>{returnmap.set('error',null).set('users',action.payload.users).set('status','INIT')})case'FETCH_USERS_FAIL':returnstate.set('error',action.payload.error).set('status','INIT')returnstate.set('error',action.payload.error).set('status','INIT')default:returnstate}}
The example above defines the following state machine:
In words:
- When the status is
INITand the action type isFETCH_USERS, the machine transitions toIN_PROGRESSstatus. - When the status is
IN_PROGRESSand the action type isFETCH_USERS_RESPONSEorFETCH_USERS_FAIL, the machine transitions to theINIT(initial) status.
You don't need redux-machine, since you can accomplish almost the same thing as in the example above by definingfetchUsersReducer as follows:
constfetchUsersReducer=(state,action)=>{switch(state.get(status)){case'INIT':returninitReducer(state,action)case'IN_PROGRESS':returninProgressReducer(state,action)default:returninitReducer(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.
These examples use thenon-immutable-js version of redux-machine.
About
A tiny lib for creating state machines as swappable Redux reducers that operate on Immutable JS maps
Resources
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Packages0
Contributors2
Uh oh!
There was an error while loading.Please reload this page.

