Redux middleware/reducer to use xstate with redux
NPM:
$ npm install --save xstate-redux
Yarn:
yarn add xstate-redux
In ES6:
import {
resetMachineStateAction,
setMachineStateAction,
XSTATE_RESET_MACHINE_STATE,
XSTATE_SET_MACHINE_STATE,
XstateRedux
} from 'xstate-redux'
Create store:
import { applyMiddleware, combineReducers, createStore } from 'redux'
import { Machine } from 'xstate'
import { XstateRedux } from 'xstate-redux'
const machine = Machine({
initial: 'green',
states: {
green: { on: { TIMER: 'yellow' } },
yellow: { on: { TIMER: 'green' } }
}
})
const reduxMachine = new XstateRedux(machine)
const reducers = {
xstate: reduxMachine.createReducer()
}
const middlewares = [reduxMachine.createMiddleware()]
const store = createStore(
combineLazyReducers(reducers),
applyMiddleware(...middlewares)
)
Make a transition with dispatch
:
console.log(store.getState())
// Initial state => { xstate: 'green' }
store.dispatch({ type: 'TIMER' })
console.log(store.getState())
// State after transition => { xstate: 'yellow' }
Code splitting: For code splitting, we need to create a new machine.
import('./red_state')
.then(({ red }) => { // red = { on: { TIMER: 'green' } }
// Create new xstate machine that can perform a transition from yellow to red state
const nextMachine = Machine({
initial: 'green',
states: {
green: { on: { TIMER: 'yellow' } },
yellow: { on: { TIMER: 'red' } },
red
}
})
console.log(store.getState())
// State before transition => { xstate: 'yellow' }
reduxMachine.setMachine(nextMachine)
store.dispatch({ type: 'TIMER' })
console.log(store.getState())
// State after transition => { xstate: 'red' }
})
Returns reset machine state action
Returns set machine state action
Arguments:
newState
(Object): new current machine state
reset machine state action type
set machine state action type
Enable code splitting for redux middlewares
Constructor:
- [
machine
] (Machine): xstate machine
Methods:
- createMiddleware(options): returns redux middleware
- [
options={}
] (Object):- [
getState=defaultGetState
] (Function): use to retreive machine state in redux store (usefull if you don't want to call your reducerxstate
). This function receivedstore.getState()
as first argument and must return current machine state.
- [
- [
- createReducer(): returns redux reducer
- setMachine(machine): set current machine
machine
(Machine): xstate machine