How we used state machines to improve state management

State management is hard. When the app state becomes unpredictable it leads to all kinds of UI errors. But it doesn’t have to be this way. In this post, we’ll see how to solve this problem using state machines.

The Problem with state management

UNCERTAIN CHANGES IN STATE

In my one project, I faced an issue with my payment module was for creating a cart. When users select membership we create a cart and for that, we dispatch cart_create action. Ideally, you would only dispatch cart_create action once. But what If for some bug in your code, we dispatch this action twice. Because redux is not opinionated about the end state it will create duplicate carts.

And to our surprise, we saw a rise in our cart creation numbers but on the other hand activation number of the order were the same :D

The typical way to handle these kinds of issues in redux is to add a check condition for the current state.

But if we use state machines, this kind of state management issue will never happen in the first place.

How State Machine can help?

A state machine is a mathematical model of computation. It is an abstract machine that can be in exactly one of a finite number of states at any given time.

This means that all the possible states of machines will have to be pre-defined. And because we would never define a state where there is a possibility of duplicate states like duplicate carts.

This makes state management easy and in turn, keeps UI more predictable. It makes UI easy to debug and results in fewer bugs overall.

How State Machine Work?

So before defining a state for that first we define the process of that.

  • We display the form with the respective field
  • User fill the field and click on Login Button
  • Call API for authentication
  • parse the retrieved data and redirect to the user on the authenticated page
  • If error then displays an error message and again shows the “Login Button” and on trigger the same process start.

So now we are thinking about the State of this process How many states we have for this process and what is the input for that process?

Idle

SubmitButton :
when users fill the form and press the submit button we call the API and transition to the machine on the LoginProcess state.

LoginProcess

Success :
If a response with success status and data then we redirect to the user

Failure :
If a response has some error then transition to the machine on the Error state.

Error

retry :
when again click on the button we start the same process and transition to the machine on the LoginProcess state.

login form state machine

Here the simple graphical representation of the above process.

Now to create a machine for this representation.

const machine = {
state: 'idle',
transitions: {
'idle': {
submitButton: function() {
changeState("LoginProcess");
const response = authAPI.data().then();
try {
dispatch('success');
}
catch(error) {
dispatch('failure', error);
}
}
},
'LoginProcess': {
success: function() {
redirectTOAuthenticatedPage();
},
failure: function() {
changeState("error");
}
},
'error': {
'retry': function() {
changeState("idle");
dispatch("submitButton");
}
}
}
}
machine.dispatch("submitButton");

So in the above code first our machine will be in an Idle state. When users click on the button first we change the machine state and then call the API. Base on the API response we dispatch the success and failure state.

On success, we redirect the user. On failure, we change our machine state. On error state, we will retry action in which we dispatch the submit button.

So, that’s how we can implement state machine without the use of any third party library
but you could also use a library like XState for this purpose.

So by using this approach we solve uncertain changes in the state which I explained earlier because the state machine can only dispatch those events which are presenting in the current state. If the machine in an idle state then it cannot dispatch the “retry” event and result in an undesired state.

Also, the machine is itself acts as documentation for UI flow. If you read all the states in a state machine and get the Idea about the entire UI flow and its states.

Conclusion:

Reference :

Software developer, Love Programming, Work in React, Redux, Javascript, PHP. Next goal to learn Go/Ruby

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store