All Projects → mheiber → Redux Machine

mheiber / Redux Machine

A tiny library (12 lines) for creating state machines in Redux apps

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Redux Machine

statebot-sh
Statebot for shell-scripts. Write more robust and understandable programs.
Stars: ✭ 14 (-95.86%)
Mutual labels:  state-management, state-machine
useStateMachine
The <1 kb state machine hook for React
Stars: ✭ 2,231 (+560.06%)
Mutual labels:  state-management, state-machine
riduce
Get rid of your reducer boilerplate! Zero hassle state management that's typed, flexible and scalable.
Stars: ✭ 14 (-95.86%)
Mutual labels:  state-management, reducer
redux-leaves
Write once. Reduce anywhere.
Stars: ✭ 52 (-84.62%)
Mutual labels:  state-management, reducer
react-stateful-component
Functional stateful React components with sideEffect support
Stars: ✭ 19 (-94.38%)
Mutual labels:  state-management, reducer
kstatemachine
KStateMachine is a Kotlin DSL library for creating finite state machines (FSM) and hierarchical state machines (HSM).
Stars: ✭ 63 (-81.36%)
Mutual labels:  state-management, state-machine
RxReduxK
Micro-framework for Redux implemented in Kotlin
Stars: ✭ 65 (-80.77%)
Mutual labels:  state-management, reducer
tstate-machine
TypeScript implementation of State Manager(like StateMachine)
Stars: ✭ 20 (-94.08%)
Mutual labels:  state-management, state-machine
statebot
Write more robust and understandable programs. Statebot hopes to make Finite State Machines a little more accessible.
Stars: ✭ 24 (-92.9%)
Mutual labels:  state-management, state-machine
xstate-cpp-generator
C++ State Machine generator for Xstate
Stars: ✭ 33 (-90.24%)
Mutual labels:  state-management, state-machine
Redux Orm
A small, simple and immutable ORM to manage relational data in your Redux store.
Stars: ✭ 2,922 (+764.5%)
Mutual labels:  state-management, reducer
Beedle
A tiny library inspired by Redux & Vuex to help you manage state in your JavaScript apps
Stars: ✭ 329 (-2.66%)
Mutual labels:  state-machine, state-management
flow-state
UI state management with RxJS.
Stars: ✭ 33 (-90.24%)
Mutual labels:  state-management, reducer
React Recomponent
🥫 Reason-style reducer components for React using ES6 classes.
Stars: ✭ 272 (-19.53%)
Mutual labels:  state-management, reducer
use-state-machine
Use Finite State Machines with React Hooks
Stars: ✭ 28 (-91.72%)
Mutual labels:  state-management, state-machine
fs2-es
Event sourcing utilities for FS2
Stars: ✭ 75 (-77.81%)
Mutual labels:  state-management, state-machine
redux-interactions
Composing UI as a set of interactions
Stars: ✭ 22 (-93.49%)
Mutual labels:  state-management, reducer
xstate
State machines and statecharts for the modern web.
Stars: ✭ 21,286 (+6197.63%)
Mutual labels:  state-management, state-machine
xstate-viz
Visualizer for XState machines
Stars: ✭ 274 (-18.93%)
Mutual labels:  state-management, state-machine
zedux
⚡ A high-level, declarative, composable form of Redux https://bowheart.github.io/zedux/
Stars: ✭ 43 (-87.28%)
Mutual labels:  state-management, state-machine

redux-machine

redux-machine

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

If you are using Immutable JS in your stores, see redux-machine-immutable.

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 Object.assign({}, state, {
            error: null,
            // transition to a different status!
            status: 'IN_PROGRESS'
    })
    default:
        return state
    }
}

const inProgressReducer = (state = {}, action) => {
    switch (action.type) {
    case 'FETCH_USERS_RESPONSE':
        return Object.assign({}, state, {
            error: null,
            users: action.payload.users,
            // transition to a different status!
            status: 'INIT'
        })
    case 'FETCH_USERS_FAIL':
        return Object.assign({}, state, {
            error: action.payload.error,
            // transition to a different status!
            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.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.

Supporting an Extra Argument

redux-machine supports to passing an extra argument to state reducers, for cases where a state reducer requires a third argument for other state it depends on.

Asynchronous Effects

redux-machine doesn't prescribe a way of handling asynchronous effects such as API calls. This leaves it open for you to use no async effects library, redux-loop, redux-thunk, redux-saga, redux-funk or anything else.

Examples

See the Redux Funk Examples repo for examples using redux-machine and redux-funk:

See the Redux Saga Examples for comparison.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].