newsletter

State management that scales with state machines

State starts simple, but it will grow complex eventually. useState doesn't fit well with this increase in complexity, but state machines do. Let's see how.


Sandro Maglione

Sandro Maglione

Software development

I am seeking "state management" in the wild 👀

Many interesting examples of "state management" everywhere, they all can be reduced to "ah, that's a state machine" 💡

I am implementing some of them for my upcoming XState getting started course:

  • Searching
  • Games
  • Modals
  • Notifications
  • Forms

Let me guide you on how I see state around me 📖


"useState works well enough here" cit.

Every wall starts with one brick.

Why would you need a crane at all? Placing one brick after the other works well enough. A crane is over-engineering here.

That's insane to say if you want to build an house. This's what most developers out there are doing with state management.

Everything starts small. But eventually you want to make something complex. You better be prepared to scale your solution. Better be prepared from the start.

Searching

Example: a searching box.

The user types some text and gets the results matching the search query

Looks simple enough at the beginning:

  • Place the search text in a useState
  • Place search results in another useState (initially empty)
  • onSubmit send an async request and update search results

It works well enough. Until it doesn't. Let me illustrate reality:

  • What happens if the request fails? Show an error message? Another useState?
  • New requirement: search as the user types. When do you send the request? How many requests? Debounce? Abort previous requests?
  • New requirement: the user can click on a result and see its details. Is this a modal? Should search be disabled when the modal is open? What if the user opens the modal while the request is in progress, suddenly we update the state, and lose all the details about the current result?

"The only constant is change"

Growing complexity will eventually crash your will in maintaining useState and useEffect spaghetti code.

Searching is a state machine:

  • Idle: showing search results (initially empty)
  • UpdatedSearch: search query updated, but request not yet committed
  • 👆👇 Debounce time from UpdatedSearch to Searching
  • Searching: request in progress
  • SearchError: something went wrong with the request
  • Opened: open details of single item

What started as a simple "Search and show results" turned into a complete state machineWhat started as a simple "Search and show results" turned into a complete state machine

XState machine

Games

Did you know? In game development state machines are the standard strategy to handle all sort of state.

Things tend to get complex when moving a game character around, especially when the character can fly, double jump, wall climb, shoot lasers, and whatnotThings tend to get complex when moving a game character around, especially when the character can fly, double jump, wall climb, shoot lasers, and whatnot

No game dev says: "State machines are not for me, it's over-engineering".

I implemented an example of NPC (Non-player character) state machine using XState (ironically in game dev it's called an "AI"):

The NPC stays stills until the mouse gets too close, then it starts chasing and attacking when close enough!The NPC stays stills until the mouse gets too close, then it starts chasing and attacking when close enough!

XState machine

Not sure how insane this would become without state machines 🤯

Bridge the gap

I personally go straight to an XState machine from the start. I've experienced too many projects going bad because state turned from useState to "we need a state machine here, but no time to refactor".

A solution in between is @xstate/store:

It's like XState without states, only context. You get inferred types and a similar XState UX. When it's time to switch to state machines (the time will come), @xstate/store is just a simple refactoring away from it.


You may have noticed I am adamant about state machines in UI development.

I aim to bridge the complexity gap in my upcoming XState course (all free of course).

It goes from useState/useEffect, their problems, useReducer, its problem, and all the way to state machines and XState.

Working on it 👨‍💻


The release of the effect course is approaching 👀

I am building a bunch of material that will be released all for free in the upcoming weeks. Wait for it 🔜

See you next 👋

Start here.

Timeless coding principles, practices, and tools that make a difference, regardless of your language or framework, delivered in your inbox every week.