DEV Community

Discussion on: No, disabling a button is not app logic.

Collapse
 
yuriykulikov profile image
Yuriy Kulikov • Edited

Please never use state machines for UI. It is a terrible idea proven to me by 3 big projects (1-10 million LOC) which have done that.

Dog fetching issue can be solved with RxJS switchMap.

Collapse
 
savagepixie profile image
SavagePixie

Would you mind sharing the highlights of your experience with those three projects that made you realise state machines were a bad idea for UIs?

Collapse
 
yuriykulikov profile image
Yuriy Kulikov

I have to be careful with the details, so I will only summarize what is already available to the public. I have participated in several projects for major car manufacturers. Three projects were built using a UI framework, which was based on a HFSM. There were a lot of states (a lot!) and the interfaces themselves were quite sofisticated. Many external factors were also taken into account, for example what happens if the car moves and some functionality must be disabled. These projects had from 1 to 10 million LOC in Java just to feed the HFSM with events.
Despite good tooling (visualization), it was an unmaintainable mess. State machine did not actually made the code more maintainable, mostly because state machine was a bad model for the UI. In the end there were clusters of states which were interconnected in every possible way. There were dedicated developers who had to maintain this state machine. I was lucky to participate in another project, which has a very similar user interface (you wouldn't tell the difference), but this time without any tooling or an abstraction for the UI navigation. Well, it was also a mess with your usual "of click here, go there, unless there is disabled, then go elsewhere". But it was actually much, much better. We have experimented with other approaches. I personally find decision trees very practical if the interface is dynamic and has to take a lot of external events into account. And it always makes sense to make user interface hierarchical, for example using nested routing outlets. For simple UI you can get away with a simple backstack.

Collapse
 
davidkpiano profile image
David K. 🎹

Lol you're already using state machines. RxJS operators and observables are state machines.

The state explosion problem is solved with hierarchical states, which XState supports.

Collapse
 
yuriykulikov profile image
Yuriy Kulikov

Not everything stateful is a state machine. I all for hierarchical state machines (actually I use them in most of my projects and I even have an open source library for HFSM). But it is not applicable for every task at hand. User Interface is one thing which rarely can be implemented with a SM in a maintainable way.

Thread Thread
 
davidkpiano profile image
David K. 🎹

Tell that to the many developers using state machines in user interfaces already (for years) with great success.

Of course it's not applicable for every use-case, but saying it's rarely useful without evidence is not helpful.

Thread Thread
 
macsikora profile image
Pragmatic Maciej • Edited

Nobody argues that every app form a state machine. The argue is should it be explicit or implicit one. I am for making not possible state not possible, but I see precise types (sums) as a tool for achieving the most. Runtime FSM looks like overcomplicating the problem.

Thread Thread
 
davidkpiano profile image
David K. 🎹

That's fine, my goal is to get developers thinking about their apps in terms of finite states and preventing impossible states. It's up to you whether you want to use a runtime FSM or not.