State-driven interfaces with XState
Hey đź‘‹
Diky Arga
Frontend Developer di Toserba Online Bukalapak

What's State?
Basically, we as frontend engineer is paid to manage states
A state is a representation of a system in a given time. State refers to the data stored in Application in the form of a string, arrays, object, etc.
ex. is user logged-in? is fetching products? is any filter applied? is product discounted?
How do we manage state?
Example
What could go wrong?
- What if fetch fails?
- What if user tap the button twice?
- What if user want to cancel fetch request?
- Disable button when fetching
- Show loading progress
- Show error message
The problems with
Event Driven Interfaces
- The code doesn’t accurately represent our component’s intended behavior
boolean variable like isLoading, isError and isSuccess is hard to manage and error prone - Not declarative
- No separation of concerns
A batter way
State Driven Interfaces
Finite State Machine
FSM
What is?

FSM for developing UI?

XState
 JavaScript state machines and statecharts
by David K Piano
Let's simplify our life
by rewriting our owsem app with state machine
Advantages
- Declarative (named state, listed all possible state)
- Easier to test
- Separation of concerns (view, logic, data fetch)
- Framework Agnostic
- Visualization
- Common language between developer and designer
The cool things about XState
XState Vizualizer

yarn add @xstate/fsm
Only 1 KB
Do we really need library like XState?
No
function dogReducer(state, event) {
switch (event.type) {
case "FETCH":
return {
...state,
status: "loading"
};
case "RESOLVE":
return {
...state,
status: "success",
dog: event.data
};
case "REJECT":
return {
...state,
status: "failure",
error: event.error
};
case "CANCEL":
return {
...state,
status: "idle"
};
default:
return state;
}
}
const initialState = {
status: "idle",
dog: null,
error: null
};
you can use reducer
No
function DogFetcher() {
// 'idle' or 'loading' or 'success' or 'error'
const [status, setStatus] = useState('idle');
}
you can use as simple as useState
Already miss isLoading?
function DogFetcher() {
// 'idle' or 'loading' or 'success' or 'error'
const [status, setStatus] = useState('idle');
const isLoading = status === 'loading';
return (
// ...
<button disabled={isLoading}>
{/* ... */}
</button>
// ...
);
}
Trade-off with State Machine
talkMachine.send('done')
<ThankYou/>
talkMachine.send('QnATime')
references
Statedriven interfaces with XState
By Diky Arga
Statedriven interfaces with XState
- 492