Fair enough, but what's a rudimentary usecase for 'the modern web'?
What everyday UI thing is better done with this than other methods? Why is it better?
Fair enough, but what's a rudimentary usecase for 'the modern web'?
What everyday UI thing is better done with this than other methods? Why is it better?
Lots of frameworks and state management libraries already lean towards helpful design, in languages with async and ADTs as first-class citizens you've got a real leg up, but at the end of the day it comes down to preventing impossible states.
You can't have an error message when in the success state, you can't have success data while loading or waiting.
By preventing this at compiletime, it also means the UI can't ever show bogus data (i.e. it's impossible to have a success screen with the error message dangling at the bottom because somebody forgot to clear it)
But once you start having much more than that, or nested states, Statecharts makes it really easy to build reliable, performant and easy to change flows.
A state machine is the wrong solution unless you also need to restrict transitions themselves in my opinion
If a TS typed switch statement, say, offers the same guarantees of covering all options yet is just run of the mill JS that anyone can read and instantly grok, and covers 99% of usecases in run of the mill web dev product work, then to me that's an argument that it's the better solution.
Example: Even typing into a text box on Hacker News is a new UI state: you have a different set of shortcuts, the keyboard works slightly differently, the browser has to keep track of the input if you suddenly press back and then forward again (some browsers maintain input in these cases), undo has to work within the scope of the textbox etc.
The more complex your UI becomes, the more contradictory states become, and need to be tracked. We're posting something over XHR/WebSockets? X amount of elements on the page have to be disabled, some state has to updated with save progress etc. We are logged in/logged out? We need to show a different state. There's an error in some part of the app? We need to block user from doing something and show errors etc.
If you can split those into actual states and allow interface and actions based on the current state, it becomes easier to reason about what is going on ini your app
All of them.
> Why is it better?
Because it specifies a workflow that actually matches what you want to do instead of employing a pile of ad-hoc rules that quickly become an unmaintainable mess.
If you have animations and async calls and multiple screens/pages, you have an application with application states which transition in response to inputs. That's what state machines are designed to handle.
Storyboards are state machines. Navigation components are state machines. UI binding layers like redux are state machines.
I am not saying you're wrong, but if you're right this would be the first case I've seen of it in my career so far :-)
Truthfully, using state machines at runtime for the use cases above is sometimes too heavy. That distinction is actually a big input to what I’ve been building at Dopt.
Our platform lets you build state machines that are initialized per user in your application via our SDKs—you design the machines in the platform, and we provide APIs to let you transition them based on user interaction/input. We’ve taken a bunch of inspiration from Xstate and statecharts. I actually wrote up a blog about how we took inspiration from the latter https://blog.dopt.com/state-machines-and-their-influence-on-...
IMO the JSON was hard to read, but we had a plan to build a GUI config builder that exported the state flows.
Emphasis on attempted, not sure I've ever seen it actually work as envisioned. Can see how bringing this directly into the code could remove some hurdles though.
Must say though I am a little skeptical on the readability / comprehensibility of the JSON format as you point out, but it's certainly a cool idea.
[1] https://web.stanford.edu/class/archive/cs/cs103/cs103.1142/b... (requires pointer and not touch input)
Why? Can you give an example?
It’s the same situation as redux though but with more formality and it’ll draw you a nice diagram too.
“Hey ChatGPT, can you show me an example of using XState typescript library to separate business logic from UI code in a computer program and discuss why XState might be useful for this purpose?”
The example it gives is really incredible… and obviously you can refine what it’s doing in context for your own understanding.
Another example is sending and receiving state changes from anywhere other than the UI, such as via WebSockets in a collaborative editing environment.
Not trying to be pedantic I promise, I really want to see the value of this, but not sure I can without an example clearly comparing this against just a few if statements or something in pure JS, for something 'everyday'.
State machines make sense to me in a theoretical sense for something with a pretty complex tree of state transitions like a game but for the 99% run of the mill UI work you get in building web products I am not sure I see anything that brings value worth the tradeoff of having to learn yet another library.
Its original value prop was one way data flow and pure functional UI based on passed in props. It allows for side effects, to get certain things done pragmatically, but in my view does not encourage them in any way.
And it's true that this separation of state and UI is just a general design pattern, which can be implemented with a plain object and switch statement, or a small class with a few methods - it doesn't have to be state machines.
So I'm with you in your conclusion, or skepticism perhaps - I prefer to apply the minimal pattern that achieves the same thing, rather than having to learn another state management library like Xstate or even Redux. But then again, I can see the value of such a library in a group/company environment, where you want everyone to learn and follow certain ways of organizing things, where new members can read the documentation, and understand how to add and change existing code in a predictable pattern.