In this talk, I will describe how to use xState to implement state machine and state charts and create highly predictable user interfaces.
Presentation from https://www.meetup.com/ReactNYC/events/259413726/
5. Finite State Machine – ex: traffic light
• Finite amount of states
• Predetermined sequenced transitions
Green Red
Yellow
TIME
R
TIME
R
TIME
R
• Events triggers transitions
6. State Chart
created by David Harel in 1987
A state chart is a state machine
composed of other state
machines called sub-states.
Sub-states can be state charts
themselves (compound states)
or remain atomic.
Allow for advanced state
composition using hierarchical,
historic and parallel states.
7. State Chart – ex: traffic light
Green
Yellow
TIME
R
TIME
R
TIME
R
Red
8. State Chart – ex: traffic light
Green
Yellow
TIME
R
TIME
R
TIME
R
Wal
k
Wai
t
Sto
p
PED_TIM
ER
PED_TIM
ER
Red
9. Okay… but why? 9
• Tried-and-true methodology for modeling
applications
• Makes the impossible impossible
• Allow for application logic visualization
18. Global State Chart – Events
Browsing Selecting
SELECT_ITEM
DESELECT_ITEM
(if selectedItems.length <= 0)
RESET_SELECTION
SELECT_ITEM
DESELECT_ITEM
(if selectedItems.length > 0)
Deleting
DELETE_SELECTION
DELETE_SELECTION_FAILURE
DELETE_SELECTION_SUCCESS
Promptin
g
DISMISS_PROMPT
19. Global State Chart – Events
Browsing Selecting
SELECT_ITEM
DESELECT_ITEM
(if selectedItems.length <= 0)
RESET_SELECTION
SELECT_ITEM
DESELECT_ITEM
(if selectedItems.length > 0)
Deleting
DELETE_SELECTION
DELETE_SELECTION_FAILURE
DELETE_SELECTION_SUCCESS
Promptin
g
DISMISS_PROMPT
20. xState – Events 20
Composed of a type and an
optional payload
Payload is then handed over to
actions for side-effect purpose
Events cause a state machine to transition from its current state to
the next
type IAppEvent =
| { type: 'SELECT_ITEM', item }
| { type: 'SELECT_ALL_ITEMS’ }
| { type: 'DESELECT_ITEM', item }
| { type: 'DELETE_SELECTION’ }
| { type: 'SELECTION_DELETED’ }
| { type: 'RESET_SELECTION’ }
| { type: 'DISMISS_PROMPT' };
26. xState – Actions 26
Actions are fire and forget
side effects triggered upon
state machine transitions
• Three types of actions:
• Entry: executed upon
entering a state
• Exit: executed upon
exiting a state
• Transition: executed
when a transition is
triggered by an event
states: {
browsing: {
onEntry: ['loadItems', 'triggerAnalytics’],
onExit: 'triggerAnalytics’,
on: {
SELECT_ITEM: {
target: 'selecting’,
actions: 'addItemToSelection’
},
SELECT_ALL_ITEMS: {
target: 'selecting’,
actions: 'addAllItemsToSelection’
}
}
},
selecting: {...},
deleting: {...},
prompting: {...}
}
27. xState – Context 27
• Contains quantitative
data (strings, numbers,
objects, etc.)
• Represents the
“extended state”
managed by the
machine
• Used to hydrate the
application components
• Updated using actions
const initialAppContext: IAppContext = {
items: initialAppContextItems,
selectedItems: []
}
const initialAppContextItems = [{
id: 0,
title: 'Summer Photos’,
owner: 'Anthony Stevens’,
updatedAt: new Date(Date.UTC(2017,6,12))
},
...
]
30. Global State Chart – Asynchronous Calls
Browsing Selecting
SELECT_ITEM
DESELECT_ITEM
(if selectedItems.length <= 0)
RESET_SELECTION
SELECT_ITEM
DESELECT_ITEM
(if selectedItems.length > 0)
Deleting
DELETE_SELECTION
DELETE_SELECTION_FAILURE
DELETE_SELECTION_SUCCESS
Promptin
g
DISMISS_PROMPT
31. Global State Chart - Asynchronous Calls
Browsing Selecting
SELECT_ITEM
DESELECT_ITEM
(if selectedItems.length <= 0)
RESET_SELECTION
SELECT_ITEM
DESELECT_ITEM
(if selectedItems.length > 0)
Deleting
DELETE_SELECTION
DELETE_SELECTION_FAILURE
DELETE_SELECTION_SUCCESS
Promptin
g
DISMISS_PROMPT
32. xState – Asynchronous calls (invoke) 32
For asynchronous calls, xState relies on Promises
• onDone transition is invoked when
the promise resolve()
• onError transition is invoked if the
promise reject()
34. Hook xState machine to React
Using the official useMachine hook from @xstate/react
https://github.com/davidkpiano/xstate/tree/master/packages/xstate-
react#readme
36. xState – Matching state 36
current.matches(’…’) provides the
ability to set conditional statement
against the machine state.
37. xState – Matching state 37
=> current.matches(’browsing’) => current.matches(’selecting’)
38. xState – Triggering State Transitions 38
Transitions are triggered by sending an event to the machine using send({…})
Transitions can also be
triggered using the
Machine.transition({…})
method which requires the
state to transition.
40. A few take away
Pros Cons
• Self documented and captures the
complete picture
• Explicit and easy to understand
thanks to state charts
• Behavior can be tested independently
from presentation layer
• State charts scale very well due to
their inherent composability
• Can accommodate complex use
cases (services, compound vs
parallel, etc.)
• New paradigm to consider
• Requires a complete picture of the
system so it can be transcribed into
state charts
• Uncovers a different set of problem to
solve around state composition (state vs
context, sub-states)
43. Stay in touch:
• xavier.lozinguez@jet.com
• @xlozinguez (Github, Twitter)
• http://xavier.lozinguez.com
Example Code:
• https://codesandbox.io/s/k06kloqzyo
• https://github.com/xlozinguez/xstate-demo
Editor's Notes
A state machine is a finite set of states that can transition to each other deterministically due to events
- The term state used within the statechart formalism simply describes a textual label which drives our program in understanding what needs to happen.
- To the contrary, in the React world the term state usually describes some data that we use to render our components.
------
Finite amount of states between which the machine transition in a predetermined sequence using events.
A state machine is a finite set of states that can transition to each other deterministically due to events
- The term state used within the statechart formalism simply describes a textual label which drives our program in understanding what needs to happen.
- To the contrary, in the React world the term state usually describes some data that we use to render our components.
A state machine is a finite set of states that can transition to each other deterministically due to events
- The term state used within the statechart formalism simply describes a textual label which drives our program in understanding what needs to happen.
- To the contrary, in the React world the term state usually describes some data that we use to render our components.
While finite states are well-defined in finite state machines and statecharts, state that represents quantitative data (e.g., arbitrary strings, numbers, objects, etc.) that can be potentially infinite is represented as extended state instead
Recommended rules:
Never mutate the context, use assign({ … }) to preserve state history
Never mutate the context externally
Unit Test your actions!
Machines can talk to each other using the `invoke` method
https://xstate.js.org/docs/guides/communication.html
By modeling the UI logic as a statechart, not only do you have full visibility into all edge cases, but adding/removing/modifying features becomes much easier and less bug-prone, since you instantly know all parts of your UI logic that feature will affect.