Hacker News new | past | comments | ask | show | jobs | submit login

Author here!

I wrote this post last summer after getting a chance to use Robot on a project to manage some complex state, and wanted to write an "intro to state machines" in the context of React.

We used it for things like scheduled periodic syncing of data to the server, managing app initialization when data could come from the server or localStorage and could fail (in an offline setting), and a couple other things. It gave us a lot of confidence in the code and I thought it'd be worthwhile to try to get the idea of state machines in front of more people, with a simple (and somewhat contrived for the sake of) example.

From the other comments I gather folks are taking this as a recommendation to use a state machine for modal dialogs, or a suggestion that this is necessary in React. My intent was more to introduce the concept of state machines with a simple example, not so much to say this is the right way to build modal dialogs :D

I think state machines can really help simplify some kinds of problems, and I've been on the lookout for places where they're a good fit. I'd be interested to hear examples where a state machine was useful in code you've worked with.




> My intent was more to introduce the concept of state machines with a simple example ...

Okay, so, I have a question about state machines but I’ve been too embarrassed to ask on HN. This is my opportunity, so I’m gonna jump right in.

My question is: why don’t we see state machines _absolutely everywhere_? Or, do we, and I just haven’t appreciated it?

They’ve been introduced in the article as a great new alternative to - presumably - whatever you’ve been doing to manage your (in this case, UI) state up until now. But aren’t state machines self-evidently the best way to manage any arbitrarily complex combination of states and transitions, regardless of the problem domain, language, etc? What are the sane alternatives?

A number of commenters to this thread have said something along the lines of: if you’re not using state machines, you’re using state machines without knowing it. Perhaps that explains the blind spot?

All this being the case, why do they seem to get so few explicit mentions, eg, here on HN or on SO or otherwise?

Love to hear people’s views - please set me straight!


Here's the funny thing: they are absolutely everywhere! It's just that the vast majority of them are implicit.

What I mean by this is you can describe virtually every piece of "logic" in an app as a state machine - there are "behaviors" (finite states) that might change (transitions) due to something that happens (events).

The problem is that there are many ways developers wire those up, where the finite states, transitions, and events are there, but it's difficult to enumerate them clearly.

So why doesn't everyone use explicit state machines? Simply because languages make it easier to write implicit state machines (e.g., async/await), and it's the path of least resistance to getting code to "just work". Unfortunately, most developers care about the frictionless path rather than the most robust path, especially in this startup-driven world.


I think it's a few things, but the two that seem most apparent are (1) that not that many people know about them, and (2) that they feel like overengineering, too much work, or just too hard when you can just write the code the normal way.

For me, I learned about state machines during my CS degree. They seemed like a neat curiosity, and we drew out our DFA diagrams and whatever, and then I mostly forgot about them. My classes never tied that theoretical knowledge to actual code or real-life examples of when something like a state machine would be useful. If anything, a lot of the examples made them seem like a crappier way to hand-make regular expression, and that made them seem pretty unappealing.

I definitely understand the overengineering complaint, because the code comes out more verbose, takes more thinking to write and read, and forces you to handle all the edge cases that you might normally ignore because "they'll never happen". I still have some resistance to reaching for a state machine, I definitely don't use them for everything.

They've been very useful for a couple recent problems though:

Building a "preset manager" for a screen recorder app. You can have a preset selected, or not. A preset auto-populates the choices for screen, resolution, and mic. If someone changes one of those preset values, or you pull the plug on the mic that's selected, the UI needs to clearly indicate you're not matched with the preset anymore. There were a looooot of fiddly edge cases here and a state machine was a huge help in keeping it tidy, and ensuring that it actually works all the time. I tried to do it without a state machine at first but it got very hard to be sure all the pieces were doing the right thing.

Trial expiration and license management. The app can be in trial, expired, or licensed. Simple enough! But there are other situations, like the license on disk is corrupt, or the trial data is corrupt. The state machine was a big help in making sure I thought through every transition that could happen. Also really nice to have a centralized place for this logic, and the machine can dispatch notifications, so other parts of the app can react as needed.


In my opinion, state machines are the best solution when you have "any arbitrarily complex combination of states and transitions, regardless of the problem domain, language" to quote you. However most UI state patterns are not arbitrarily complex. Mostly we're pulling a little data and there is a loading and error state. Using a state machine to manage that is perhaps a little much compared to other solutions and provokes these responses of overengineering.

So it becomes the classic idea of the right tool for the job and knowing when to reach for the more powerful tool. I think that's the value of articles like this.


In Elm/ReasonReact before Hooks it/was the only way to write your application making impossible states unrepresentable




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: