[HN Gopher] useStateMachine: A 1/2 kb state machine hook for React
       ___________________________________________________________________
        
       useStateMachine: A 1/2 kb state machine hook for React
        
       Author : nkjoep
       Score  : 206 points
       Date   : 2021-05-21 07:01 UTC (1 days ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | wyuenho wrote:
       | Isn't the useReducer hook already an interface for building state
       | machines? The clue is in the signature of reducer functions, the
       | signature as exactly the same as textbook state transition
       | functions...
        
         | sudhirj wrote:
         | The general use reducer is a infinite state machine, while this
         | is a finite state machine. The normal reducer can allow your
         | app to be in any state, while finite state machines let you
         | list the only possible states (like ON, OFF, UNKNOWN; or
         | DRAFT,SENT,BOUNCED) - and offers state transition functions to
         | move between them that can refuse to move unless certain
         | conditions are met.
        
           | bennyg wrote:
           | This still mostly sounds like a useReducer. With TypeScript
           | you can guarantee the built code only respects a finite state
           | shape. Depending on the dispatched action, you can just
           | default to returning the previous state - refusing to move
           | unless certain conditions are met.
        
             | davidkpiano wrote:
             | Yes, you can. The vast majority of developers don't. That's
             | the difference: enforcement.
        
           | wyuenho wrote:
           | It's only a FSM if the users litter a guard function all over
           | the place, otherwise this is just some deeply nested non-
           | sugar on top of useReducer.
        
       | Waterluvian wrote:
       | I can't get over how amazing hooks are and how resistant I
       | initially was to them.
       | 
       | They encapsulate logic so well and do an amazing job being this
       | isolated data/event source.
       | 
       | I find that I reuse them far more than I reuse components.
        
         | judofyr wrote:
         | Interesting. I have the opposite experience, the more I use
         | them the more clunky they feel.
         | 
         | * If there's only useState, then everything is mostly fine. All
         | is good.
         | 
         | * To avoid unnecessary re-rendering you'll have to move
         | callbacks into useCallback. These callbacks then also need to
         | specify all of their dependencies. So many lines of code that
         | are merely noise.
         | 
         | * They encourage having state locally in the component which
         | often breaks down the moment you slightly tweak the design. So
         | much refactoring!
         | 
         | * Dealing with any other (callback-based, stateful) API is
         | confusing. If you want something to execute once initially you
         | can use useEffect with an empty dependency list, but note that
         | then there's no way of accessing updates values (in callbacks)
         | and everything will reflect the initial state. Often you'll
         | have to use useRef just to keep track of the current state. Or
         | maybe useState?
         | 
         | * Debugging is painful. You forget one value in your dependency
         | list and the weirdest things happen. Suddenly you have
         | callbacks running in different rendering scopes with different
         | values.
         | 
         | They feel very "brittle": Once it works the code looks pretty,
         | but when there's a slight change of requirements you need to
         | rethink everything.
        
           | [deleted]
        
           | jakelazaroff wrote:
           | My experience is mixed but mostly positive.
           | 
           | - Agreed about useState (and useReducer). They're simple and
           | they get the job done.
           | 
           | - Agreed about useCallback as well, it's a lot of
           | boilerplate.
           | 
           | - State in general is a hard problem to deal with, but I'm
           | not sure how hooks in particular encourage it? Class
           | components had the same issue.
           | 
           | - IMO, useEffect is a huge footgun. I understand how it
           | works, I understand how closures work, but it is by far the
           | biggest source of hook-related bugs I've experienced.
           | 
           | - This eslint plug-in will solve your dependency list woes:
           | https://www.npmjs.com/package/eslint-plugin-react-hooks
        
             | ketzo wrote:
             | +1 for that eslint plugin, I was just idly wondering if
             | something like that existed earlier this week. Thanks.
        
               | jakelazaroff wrote:
               | Unless your app is peculiar in some way I'd recommend
               | using something like Create React App, which includes it
               | automatically. https://create-react-app.dev
        
           | deergomoo wrote:
           | > To avoid unnecessary re-rendering you'll have to move
           | callbacks into useCallback. These callbacks then also need to
           | specify all of their dependencies. So many lines of code that
           | are merely noise.
           | 
           | I really like Vue 3's Composition API as a much easier-to-use
           | (IMO) implementation of hooks.
           | 
           | It's conceptually very similar to React Hooks, but the method
           | that defines them only runs once, when the component is
           | instantiated. So straight away that removes any worries
           | around conditionals and loops.
           | 
           | Instead of a plain value/object and an update function, the
           | "hooks" instead return a reactive object that tracks it's own
           | dependencies (which are also all reactive objects). That
           | removes any need to manage dependencies yourself, or for any
           | memoization.
           | 
           | The only downside is that because a plain value (like a
           | number or something) cannot be reactive, it has to be wrapped
           | in an object and accessed via a ".value" property, but this
           | is only relevant in the setup function. Anywhere else, like
           | the Options API or in the template, accessing the value like
           | a value will just get transparently proxied to the object.
        
             | nightski wrote:
             | The entire concept of reactive objects brings back memories
             | of extreme pain from KnockoutJS days (and terrible
             | performance in complex scenarios to boot). I prefer just
             | working with plain old data structures.
        
               | benatkin wrote:
               | I prefer working with just plain old setup functions,
               | that are called once.
        
           | simion314 wrote:
           | >You forget one value in your dependency list and the
           | weirdest things happen.
           | 
           | This is what I hate in angular1 , there are at least 3-4 ways
           | you can mess up a simple data-binding and there is no error
           | or warning to inform you that something is not right so you
           | waste a lot of time to figure it out.
           | 
           | I used react a few years back but it seems that this days it
           | got hyper complex.
        
             | bobthepanda wrote:
             | As far as I can tell you can just not use hooks, if you
             | (and the rest of your contributors) agree.
        
           | wayneftw wrote:
           | > You forget one value in your dependency list and the
           | weirdest things happen.
           | 
           | Don't you get eslint warnings right in your editor?
           | 
           | If you're using VS Code there's an extension for that...
        
             | Waterluvian wrote:
             | Not only this but I need the freedom to control the
             | dependency list for an effect. Sometimes it isn't as simple
             | as "every variable being referenced inside the effect."
        
           | joshribakoff wrote:
           | You can use OOP or whatever you want to build your
           | abstraction and then surface that as a hook, rather than
           | using hooks as a way to do all your logic. This is similar to
           | how there are npm packages that just import some other js
           | package "foo", wrap its api in a react component, and
           | reexport it as react-foo
           | 
           | I'm curious what you think of https://rxstore.dev/ it
           | basically is a pattern I tried to outline where you write
           | logic with rxjs and it tries to bridge the gap to react/hooks
           | for you. I address some of your points in the faq.
        
           | grandpoobah wrote:
           | > You forget one value in your dependency list and the
           | weirdest things happen
           | 
           | Really? I've been working with hooks for months, with code in
           | production, and I hardly ever pass more than one or two items
           | to the dependency list. The only time I really had any
           | trouble with dependencies was when I was updating appContext
           | inside a hook.
        
           | mikojan wrote:
           | Seconded. Plus, you start writing wrapper functions for
           | standard Javascript APIs (e. G. window.setInterval) to force
           | them into Reacts data model.
        
             | jameshart wrote:
             | ... which is a good idea anyway because you want your code
             | to be testable.
        
               | mikojan wrote:
               | ...this makes no sense at all.
        
             | erikpukinskis wrote:
             | Why would you do that? What's wrong with this?
             | useEffect(() => {           const interval =
             | setInterval(myFunc, 1000)           return () =>
             | clearInterval(myInterval)         },[])
             | 
             | I think one of the keys to React is not to fear the
             | boilerplate.
             | 
             | If you find yourself typing the same code too often,
             | there's probably a higher level abstraction that you should
             | find, way above the level of setInterval.
             | 
             | I find coders often try to DRY up low level code to the
             | detriment of actually dealing with their _application_
             | architecture.
             | 
             | In general, you should use the tools as provided,
             | boilerplate and all, and then focus your real brain
             | energies on the specific domain problems that only your
             | application needs.
             | 
             | Creating thin wrappers on external tools to squeeze the
             | last tiny bits of DRYness is not only usually a waste of
             | time, but it makes your code unreadable. People know how
             | setInterval and useEffect work. If I see useInterval I have
             | to go read your code to know what's happening. Especially
             | if you made it configurable. And people _will_ tend to add
             | configuration to these wrappers over time as needs change.
        
               | lunfard00 wrote:
               | in my experience is better to have customs hooks like
               | useTimeout (react-use library is awesome) so is easier to
               | test. Mocking hooks feels nice, mocking the browser API
               | not so much...
        
           | jimrandomh wrote:
           | > You forget one value in your dependency list and the
           | weirdest things happen.
           | 
           | There's an eslint plugin specifically for detecting this,
           | which should probably be considered mandatory.
        
           | mrighele wrote:
           | > If you want something to execute once initially you can use
           | useEffect with an empty dependency list, but note that then
           | there's no way of accessing updates values (in callbacks) and
           | everything will reflect the initial state. Often you'll have
           | to use useRef just to keep track of the current state. Or
           | maybe useState?
           | 
           | I'm not sure if I understood what you mean, but note that
           | useState accepts not only the updated state, but also a
           | function that takes the current state as argument and return
           | the updated state.
           | 
           | In other words, instead of something like this
           | 
           | useEffect( async () => {                 ...            const
           | someValue = await someFunction();
           | setState({...state, someValue });
           | 
           | }, [... ] );
           | 
           | you should use something like this
           | 
           | useEffect( async () => {                 ...            const
           | someValue = await someFunction();            setState(
           | currentState => ({...currentState, someValue }));
           | 
           | }, [ ... ] );
           | 
           | (the example is with async but it is the same for regular
           | callbacks)
        
             | jakelazaroff wrote:
             | Note that you shouldn't (can't?) actually pass an async
             | function directly to useEffect, since it returns a promise:
             | https://github.com/facebook/react/issues/14326
        
               | tanaypingalkar wrote:
               | True, you cannot do that in useEffect, it will throw you
               | error. And probably your linter will tell you. You can't
               | even use your own or third party hooks in side useEffect.
               | This also throw error I don't know why?
        
               | mrighele wrote:
               | you're right, good catch. Usually it's the TS compiler
               | that prevents me doing that.
        
               | zebnyc wrote:
               | I usually use an IIFE to encapsulate the async block
               | inside the useEffect. Works like a charm!
        
               | jacobedawson wrote:
               | Not true, see Gaeron's direct reply in the thread you
               | linked to, that's been the standard for 3 years and works
               | like a charm - useEffect specifically is the hook for
               | handling async functions ("impure effects").
        
               | azangru wrote:
               | Notice the words "pass to useEffect" in the parent
               | comment, and the code snippet in the grandparent they are
               | commenting on. The type of the callback function that
               | useEffect accepts is () => void rather than () =>
               | Promise<unknown>. What's not true about that?
        
               | jakelazaroff wrote:
               | I reworded it to make it a bit more clear (at least, I
               | thought so) -- "pass an async function to useEffect",
               | meaning the argument supplied to useEffect itself, rather
               | than "use directly within" which is ambiguous. Re-added
               | "directly" to hopefully make even more clear. Sorry for
               | the confusion!
        
             | ricardobayes wrote:
             | You can use a boolean ref for this in the useEffect to keep
             | track whether it was the first render or not.
             | https://reactjs.org/docs/hooks-faq.html#can-i-run-an-
             | effect-...
        
           | phailhaus wrote:
           | > Debugging is painful. You forget one value in your
           | dependency list and the weirdest things happen
           | 
           | This should never happen. The only downside to hooks is that
           | the eslint plugin is _required_, not optional. It is not
           | worth the pain without it, but you'll be in a Whole New World
           | once you do it. Since you can auto-fix every time, it'll
           | become second nature and you'll never forget a dependency
           | again. You can focus on getting your application to work.
        
           | schwartzworld wrote:
           | Regarding useCallback, you can probably skip it in most
           | cases, unless the extra renders are a problem for you.
           | 
           | Linters should help with missing dependencies.
        
             | ng12 wrote:
             | Yes! useCallback is an optimization and using it
             | prematurely can be problematic.
        
         | antjanus wrote:
         | that's pretty much how I feel, too. I really love the flow of
         | hooks and I write a ton of them -- majority of the logic I
         | write tend to end up in hooks and I really love that.
         | 
         | There's something to having a function that can hold state or
         | load its state on mount, etc.
        
         | k__ wrote:
         | They fit so well into React it's crazy.
         | 
         | But they're also soooo idiosyncratic which makes them rather
         | ugly on a general level.
        
           | codeflo wrote:
           | They also come with many restrictions and rules on correct
           | and efficient usage, not all of them checked by ESLint, that
           | make the learning curve a bit brutal.
           | 
           | But yes, insanely useful once you get the hang of them, they
           | enable forms of abstraction and composability that you'll
           | sorely miss when working in other UI frameworks.
        
             | radicalbyte wrote:
             | Aren't there proper TypeScript bindings which catch (more)
             | cases?
        
       | wilsonrocks wrote:
       | I'm excited to try this. I've tried xstate many times and always
       | struggled with the typescript, if this Just Works I'll be v happy
        
         | davidkpiano wrote:
         | We're constantly working on improving the TypeScript experience
         | with XState; there are some new things like `createModel()`
         | that might help!
        
           | cacozen wrote:
           | Oh, I need to try that too!
        
           | RobertKerans wrote:
           | Actions defined in options are the killer for me at the
           | minute (and guards, but actions are more important
           | generally). I've had to resort to using enums (+ type guards
           | + coercions) for everything. Have you any idea on if/when can
           | get these in the model API? At the minute the API is nice,
           | but not particularly useful with only context & events. The
           | type gen library seems to be a sticking plaster more than
           | anything else: it's clever, but building an NPM package on
           | the fly seems super fiddly (and flat out doesn't work with
           | newer Yarn setups), so movement forward on inference without
           | it would be great
        
           | wilsonrocks wrote:
           | Oooh createmodel is new to me - will check it out!
        
       | isuckatcoding wrote:
       | So I think this is basically an abstraction on top of useReducer
       | which itself is kind of a state machine pattern.
       | 
       | It's a little verbose more my liking but I think it could be
       | powerful for large apps with lots of states.
        
         | vikingcaffiene wrote:
         | This is a Finite State Machine meaning there are a limited set
         | of states and state transitions allowed. useReducer doesn't
         | have any of the state/transition validation logic which makes
         | it an infinite state machine. Both are very useful. Different
         | use cases though.
        
       | runawaybottle wrote:
       | Can anyone provide an example of a situation where something like
       | this is a pragmatic solution? Please also provide the drop dead
       | simple version too and explain why this would be more elegant and
       | intuitive in comparison.
       | 
       | Types of examples I am not interested in seeing:
       | 
       | - a DropDown list using a state machine (or something similarly
       | simple that's been solved a million times in a simple way).
       | 
       | Edit:
       | 
       | I just think stuff like this is too weird and dangerous to
       | evangelize, and I'm at my wits end in dealing with simple
       | components that have been over abstracted.
        
         | gbear0 wrote:
         | I think the value of a state machine is treating all of the
         | associated states in a single conceptual model or level. You
         | can definitely do everything directly in a bunch of if
         | statements and tracking state in separate variables, but that
         | opens yourself to more potential bugs, higher maintenance cost,
         | less big picture understanding, and even larger performance
         | costs (separate codes means the compiler can't optimize as
         | well; means hardware caches aren't as effective; there's more
         | overhead to run separated functions; etc, etc).
         | 
         | Here's hopefully a more apt example: imagine wanting to have a
         | multiple document interface (MDI) that shows a bunch of
         | 'window' like views. Some examples of the idea are react-grid-
         | layout, golden-layout, react-mosaic. Each window can be
         | minimized, maximized, moved, flashed, and closed ... all with
         | flashy animations. You could create a whole bunch of components
         | that allow you to capture all the different states and toggle
         | them in different components, and effectively have the MDI
         | business logic sprinkled all through out YOUR code, not just
         | the 'library' code. Alternatively, you could use a state
         | machine that captures all the states in a single spot and
         | manages that all efficiently and safely, you just call an api
         | to trigger state changes throughout your code.
         | 
         | As some other comments have mentioned, this is a fundamental
         | part of computer science. You can get by without knowing it
         | cause you can write a bunch of ifs and state logic all over the
         | place. If you only know how to use a hammer, ya you could still
         | hammer a screw in. Understanding how different data structures
         | of different patterns fit together provides you new tools to do
         | things in different ways when appropriate. Learn how to manage
         | complexity, not fear it, cause there's nothing dangerous about
         | state machines. In fact, I'd argue that anyone that thinks
         | state machines make things more complex just isn't looking at a
         | large enough scale because state machines should make things
         | less complex by wrapping all the complexity inside them (when
         | used appropriately).
        
           | runawaybottle wrote:
           | I'll concede I came with a contentious tone, which is
           | probably resulting in a similar retort by a few of you that
           | is mostly using appeal to authority to justify your claims
           | (eg just learn computer science bro, you must not know it).
           | 
           | Sporadic business logic/spaghetti code is a problem in any
           | application. State machines will not magically avoid this. In
           | fact, it should be just as susceptible to it. When sphagetti
           | code shows up under a complex architecture like this, you
           | could be in a world of hurt. There won't be a few if-
           | statements for you to unwrap, but instead a maze of cascading
           | state updates. Another common thing I've seen is the
           | granularity of capturing any and all state updates, and then
           | some. It's very tedious.
           | 
           | Anyway, I've been dead wrong about 70% of things in life
           | before, so I'd be happy to look at a non trivial app written
           | with xstate if anyone's got a repo.
        
             | davidkpiano wrote:
             | Sorry if I was flippant. Here is an example of a minute
             | timer app, which replicates Android's timer app behavior
             | using statecharts: https://codesandbox.io/s/xstate-vue-
             | minute-timer-viz-1txmk
             | 
             | Allow popups to see a live visualization of the statechart.
        
         | cacozen wrote:
         | I think using a state machine can make the resulting code more
         | elegant in some cases by coupling state changes and effects.
         | But that's not why they are useful. In my experience, they have
         | been useful because they help map (even mentally) all
         | individual possible states a piece of code can be in, and how
         | the code should behave in each case. In the process, I usually
         | discover and deal with more edge cases, more combination of
         | states and behavior, and as a consequence the code is
         | bigger/fatter. But also more robust.
        
         | enjeyw wrote:
         | I've needed to construct a chatbot-esque UI on more than one
         | occasion. I used a state-machine on the second time round and
         | it simplified work considerably!
        
         | davidkpiano wrote:
         | Lots of good examples here: https://xstate-catalogue.com/
         | 
         | It seems like you're just unfamiliar with state machines.
         | They're not a "new, weird abstraction", they're a core concept
         | of computer science in general, and it can be argued that most
         | code we write is itself an abstraction on top of state
         | machines; not the other way around.
         | 
         | For more information on state machines and statecharts, I
         | recommend reading this great resource: https://statecharts.dev/
        
           | runawaybottle wrote:
           | No, I know what state machines are. What I'm contesting is
           | the argument that this is an intuitive way to structure code.
           | It could be intuitive to reason about, or even white board
           | the states your application can be in, but this doesn't look
           | like concise and elegant code.
           | 
           | From your examples: https://xstate-
           | catalogue.com/machines/confirmation-dialog
           | 
           | I've written a million confirm-dialogs in my lifetime, and
           | that example is one of the most convoluted things I've ever
           | seen.
           | 
           | Guys, just because it's in Computer Science, doesn't
           | automatically mean it's a more sophisticated solution. The
           | term for this is over-kill.
        
             | fuzzy2 wrote:
             | I think your problem is that many things don't have to be a
             | state machine. And you're right. It's simply not a good
             | idea to create a confirmation dialog like that.
             | 
             | However, some things just _are_ state machines. You don't
             | usually see them in the GUI (except for example wizards),
             | but many parsers can trivially be implemented with state
             | machines.
        
               | matsemann wrote:
               | I actually believe there would be fewer UI bugs if more
               | UI was modeled as a state machine. After all, all
               | diagrams and design is often based on "when X is shown
               | and Y is pressed, we go to Z". But in code that's
               | expressed in a way that makes it possible to have a
               | mismatch between multiple half baked states.
        
             | davidkpiano wrote:
             | Nobody's forcing you to use this library. Please take your
             | negativity elsewhere.
             | 
             | EDIT: Okay, didn't mean to interpret criticism as
             | negativity; I apologize.
        
               | runawaybottle wrote:
               | Fair enough, but the echo chamber is why stuff like this
               | gains prominence. I'm abrasive for sure, but I need to
               | see some push back on these ideas in all of these
               | threads.
        
               | kaoD wrote:
               | Criticism is not negativity. It's valuable when someone
               | in the room challenges ideas and pushes back over-
               | abstraction (if done respectfully and constructively).
        
               | jhgb wrote:
               | Can you even describe the use of a state machine for UIs
               | as "over-abstraction"? To me it seems more like an
               | "under-abstraction", since one usually compiles a more
               | abstract definition into a state machine - often a
               | regular expression or some kind of grammar.
        
               | runawaybottle wrote:
               | Was just discussing this with a friend this morning. It
               | might be better to describe it in terms of trade-offs
               | versus the overuse of the 'over-abstraction' allegation.
               | 
               | So, in a lot of cases in the UI, we are turning what is
               | very recognizable and traditionally understood code into
               | a new form to fit the state-machine world view in a more
               | 1:1 way.
               | 
               | Again, it's a trade off. What did we gain from this
               | transformation? I don't think we get enough back from
               | this trade to structure our code in this new way.
               | 
               | Or to be clear, why would I trade my ability to read a
               | few simple fetch calls that update a simple DOM element
               | for this version? What is the outsized return here?
               | 
               | Just my 2 crypto.
        
               | gbear0 wrote:
               | Did you start programming with OOP or Functional
               | programming? Did learning how to programming in the other
               | form seem difficult to understand why you would do things
               | that way, or seem obtuse vs just using the ways you
               | already know?
               | 
               | I think using state machines is just a very different way
               | of looking at code, and it does take some mind bending to
               | think that way; but once you do, it's much easier to
               | blend the code together the same way you'll see
               | imperative and functional code blended together these
               | days and not think twice about it.
        
               | jhgb wrote:
               | How are state machines "a very different way of looking
               | at code"? It's basically assembly with jumps as state
               | transitions. A decent programmer already understands this
               | from assembly lessons (and avoids doing it by hand,
               | leaving it to the compiler).
        
               | [deleted]
        
           | jhgb wrote:
           | > It seems like you're just unfamiliar with state machines.
           | 
           | You're saying that he doesn't know computers? Computers are
           | state machines. Presumably he used one to post his comment.
        
         | RobertKerans wrote:
         | Auth logic or similar. Somewhere area in app that may be
         | genuinely complicated and can't go wrong, where you need
         | granular control over a set of states which often have sub
         | states, and where there are things like remote requests to
         | different services occurring.
         | 
         | And you can just write this stuff as basically lots of nested
         | if statements but...
         | 
         | As an actual example, I have a state machine in an app I work
         | on:
         | 
         | 1. check if there's a session (if so goto 4). 2. If not go to
         | email input. 3. On submit go to password input. 4. authorized.
         | However: 2 and 3 and some of the time 1 have network requests,
         | so handle those. Password can be entered wrong three times
         | (error message changes accordingly, oh also no. retries are
         | modifiable at admin level), which bumps user back to 2 (error
         | message changes accordingly). User may have turned on PIN
         | security, if so that will be an extra step before allowed into
         | app. They may also have it turned on, but not one set, which is
         | a slightly different flow. And they can turn it off/on from
         | within app. Oh and biometric, same deal as PIN. Also can drop
         | back to username/pword instead of OTP in some circumstances.
         | 
         | That's most stuff I think off top of head. That's a
         | hierarchical state machine written using XState. It's easy to
         | test (UI is seperate from the machine, and I can just plug in
         | API functions for the remote calls). It's relatively easy to
         | read (xstate API produces stuff that reads like a diagram, it's
         | easy to explain what's going on). It's easy to add/remove
         | states
        
           | runawaybottle wrote:
           | That's actually a good use case, thanks for sharing.
        
       | [deleted]
        
       | skrebbel wrote:
       | love the logo
        
         | cacozen wrote:
         | Hahaha, reused from a video on my YouTube channel, was created
         | in 5 minutes on Apple Keynote
        
       | yewenjie wrote:
       | Is there quick primer on what and why of state machines?
        
         | cacozen wrote:
         | Author here. Yes, I made a series of videos about it, starting
         | here: https://youtu.be/N0OaRdJuVlc
        
       | whoevercares wrote:
       | How does this work with RxJS or reactive pattern?
        
         | cacozen wrote:
         | It's not directly related - this is a thin layer on top of
         | useReducer and useEffect, so it's more directly tied to React.
         | But take a look at XState
        
       | DylanSp wrote:
       | Thanks for including the comparison to xstate; that's where my
       | mind immediately went when I first saw this. Are there any plans
       | to create a visualizer, similar to what xstate has?
        
         | cacozen wrote:
         | Of course, XState is a huge inspiration and the golden standard
         | of State Machines for JS. I visualizer is not on the short-term
         | plan, but there's a "verbose" mode that helps with debugging.
        
       | lloydatkinson wrote:
       | As someone that works with _finite_ state machines, I can't begin
       | to describe how annoying I find it when everyone needlessly
       | reduces the name down to just "state machine". To me, it makes it
       | seem like the people making "state machines" don't understand the
       | whole "finite" part and thus don't understand half the point.
        
         | davidkpiano wrote:
         | If the term "finite-state machine" were used instead, there
         | would inevitably be people making comments like you, but
         | instead complaining "this isn't finite, you have extra data in
         | the machine that can be infinite". The pedantry isn't helpful.
        
       | vikingcaffiene wrote:
       | It's interesting to me how certain design patterns get
       | rediscovered over the years. A few years back FSM's were a dirty
       | word for crusty Java devs. I myself avoided them for that reason.
       | Then one day I had a perfect use case for one and took the plunge
       | and was amazed by how useful a pattern it is. I'm embarrassed at
       | how long it took me to get hip to it. I'm writing a feature at my
       | job right now that makes heavy use of FSMs. Very testable and the
       | nature of the pattern means you can have a lot of confidence in
       | your state being valid. I highly recommend trying it out even if
       | you don't adopt this hook or xstate (you can make a FSM fairly
       | easily)
        
         | codemonkey-zeta wrote:
         | Finite state machines will never _not_ be useful for the same
         | reason regular expressions will always be useful. They 're a
         | supremely simple model of computation, making them easy to
         | reason about.
         | 
         | The problem with state machines in Java is not the state
         | machine's fault, it's Java's fault.
        
           | vikingcaffiene wrote:
           | I feel like you are refuting a point I didn't make. I was
           | just talking about how we re-discover patterns. My feelings
           | on Java have nothing to do with it.
        
       ___________________________________________________________________
       (page generated 2021-05-22 23:01 UTC)