I get jealous whenever I see people post their passion projects on Twitter. ✨ They typically have all of the fancy tech, with GraphQL, or super-interactive animations or just jaw-dropping performance. In my day-to-day job, I don’t handle any of those concerns. I fetch data.

The mundane reality of real-life apps

When I fetch data in one of my container components (let’s say, a user profile page), I know what to do. I’ve done it a ton of times. I scaffold out a component, complete with some state variables that typically are named data , error and loading . I load some data when it mounts, and complete the boilerplate with some conditional rendering to render different things for different states.

They all kind of look like this:

There’s a ton of state, and it looks exactly the same. Every. Single. Time. Every single time I write this, you could bet your ass I forget to reset SOME part of that state for some particular case.

Say hello to state machines

Let’s make our lives a bit easier by creating a state machine! 💥

Each of my data-fetching components can be in one out of four states — it can be idle (before it has fetched its data), pending, successful or erroneous. It can go from idle to pending, and from pending to either successful or erroneous. Once there, you could reset the state back to idle if you want.

This starts to sound a lot like a state machine. I have to admit that my knowledge on theoretical state machines is somewhat limited, but this article by Mark Shead helped me out a ton! I suggest you spend a few minutes skimming through it if you’re like me.

So let’s start constructing our state machine. A simple outline would look like this:

As you can tell, there’s not a lot going on in here. You create an instance of this ApiStateMachine thingamajig, and call the next() -method whenever you want to make the state machine change states. It takes an optional input parameter, which can indicate whether something went well or not.

The main point is that your state can be in one and only one state — it can’t be pending with an error, or idling with a result. You’ll never run the risk of forgetting any part of the state again!

Can I use this in React?

Yeah sure, why not? To make this a bit more React-y, we can make it into a higher order component:

This HOC accepts a component, and returns a new component that keeps all of this state for you, and provides both the state and a way to go to the “next” stage as props.

This way, we can rewrite most of our data-fetching pages like this:

Improving the API

Now this is starting to look pretty neat! The only thing I’m not very happy about is this .next() method. It isn’t very easy to understand how it works. Let’s fix that.

Instead of the non-descript .next() method, we can expose .pending() , .success() , .error() and even an .idle() method! Although not implemented above, our HOC can potentially make sure to warn us if we call them out of order too — which keeps the state machiny features alive for us.

Bottom line is, we still hide all of the complexity of state handling in a reusable HOC. Here’s the final no-frills version of the API state machine HOC:

Not technically a state machine, but a real-life implementation could be.

This is how you’d use it:

The usage is clean and simple too!

Reads pretty nicely, doesn’t it? I think so too.

Here’s a simple example app where you can play with the result: