I’ve noticed that Redux apps often embed ad-hoc finite state machines, with information about the current status spread out throughout reducers. I wrote a small helper for working with finite state machines in Redux called redux-machine. In this post, I’ll go into:
This is a very simple example of a state machine for working with data fetching, which will help show how to use redux-machine:
finite state machine for handling API call state in Redux
In words:
I use the term “status” instead of “state” to avoid confusion with “state” in the Redux sense. So INIT and IN_PROGRESS are statuses.
Here’s how you can implement the state machine with redux-machine:
state machine implemented with redux-machine
The special part is the become symbol, which transitions the reducer to a different status. When the status is INIT, fetchUsersReducer acts like initReducer. When the status is IN_PROGRESS, fetchUsersReducer acts like inProgressReducer.
Redux-machine keeps the current status in the store in a non-ad-hoc and explicit way. It stores the current status in the store with the STATUS key. For example, when the status is IN_PROGRESS, the value of “STATUS” is “IN_PROGRESS.”
An app can have arbitrarily many reducers created with redux-machine, and these reducers can be nested. This is helpful because any non-trivial app will have state machines within state machines. For example, if the main flow of the app is:
a simplified main flow for an app
then the statuses in fetchUsers will only be relevant when the main app status is LOGGED_IN.
redux-machine makes the current status explicit and keeps your state in the redux store. Keeping all state in the store is useful for:
redux-saga and redux-observable are good at modeling user workflows, but store status outside of the redux store.
I haven’t used redux-machine extensively yet, so would welcome feedback and suggestions.