0 day streak
javascript / expert
Snippet

Deterministic State Machines with useReducer

Using useReducer to implement a finite state machine ensures that your application transitions between states in a predictable way. By mapping allowed transitions, you prevent impossible states (like being 'loading' and 'success' simultaneously) and simplify complex logic.

snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const initialState = { status: 'idle', data: null, error: null };
function fetchReducer(state, action) {
const transitions = {
idle: { FETCH: { status: 'loading' } },
loading: { RESOLVE: { status: 'success', data: action.data }, REJECT: { status: 'failure', error: action.error } },
success: { FETCH: { status: 'loading' } },
failure: { FETCH: { status: 'loading' } }
};
const nextState = transitions[state.status][action.type];
return nextState ? { ...state, ...nextState } : state;
}
const [state, dispatch] = React.useReducer(fetchReducer, initialState);
react
Breakdown
1
const transitions = { ... }
A lookup table defining which actions are valid for each current state.
2
return nextState ? { ...state, ...nextState } : state;
Ensures the state only updates if the transition is explicitly defined for the current status.