Live data from Hacker News

useStateMachine: A ½ kb state machine hook for React

github.com

81–90 of 103 posts

Re: useStateMachine: A ½ kb state machine hook for React

#81
post #80
post #5

Earlier quoted context omitted.

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.

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.

Yes, you can. The vast majority of developers don't. That's the difference: enforcement.

Re: useStateMachine: A ½ kb state machine hook for React

#82
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.

Re: useStateMachine: A ½ kb state machine hook for React

#83

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.

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.

Re: useStateMachine: A ½ kb state machine hook for React

#84
post #10

Earlier quoted context omitted.

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 wh…

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.

Yes! useCallback is an optimization and using it prematurely can be problematic.

Re: useStateMachine: A ½ kb state machine hook for React

#85
post #10

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.

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 wh…

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.

Re: useStateMachine: A ½ kb state machine hook for React

#86

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.

Unsurprising it took people almost a decade to discover "depend()" from Meteor.

Re: useStateMachine: A ½ kb state machine hook for React

#87
post #10

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.

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 wh…

>but note that then there’s no way of accessing updates values (in callbacks)

This is by design. When you start making a component worry about what it needs to do on an update, rather than just rendering its data, you are introducing a whole new level of complexity. That's why class based React components could turn into these unwieldy confusing things where you never knew for certain what was going to render every time, because the shouldComponentUpdate method gets stuffed full of business logic.

Re: useStateMachine: A ½ kb state machine hook for React

#89

Earlier quoted context omitted.

> 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...

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."

that's a bit confusing. While you can sometimes get away with leaving out dependencies, and then you don't have to useMemo or useCallback as often, it seems like there is a much larger downside to having potentially stale values in your effect. Leaving them out to me would result in the potential for weird future bugs and race conditions.

Re: useStateMachine: A ½ kb state machine hook for React

#90

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 l…

:-) I feel you. I like to think that state machines are used where they are useful (in some games, process orchestration, generators, embedded systems, etc.). The question is more where else can they be useful given that the low hanging fruits have already been harvested.

I am using state machines to write reactive applications: https://brucou.github.io/documentation/

So far I have to say that it is a mixed experience. There is a cost to the abstraction and the indirection (that is fairly well known easy to describe even if we rarely do so due to some self-imposed no-negativity bias or having some interest in the game), and then there are the benefits that are less easy to describe because they depend highly on the nature of the problem that you are addressing.

I implemented a Medium clone application (https://codebase.show/projects/realworld) with state machines. The result is 47Kb (brought down to 39Kb after compiling the machine and other optimizations) vs. 70Kb for the Vue implementation or 160 KB for the React/Redux one (that implementation piles abstraction over abstraction in the form of libraries and pays the corresponding price). I would count that as benefit. Also cf. https://brucou.github.io/documentation/v1/tutorials/index.ht... for the full pitch.

The high-level machine is that one: https://brucou.github.io/documentation/graphs/real-world/rea...

At this level, you can follow the routing of the app. Every route is a compound state. If you open it, you see the details of the behavior. The full machine (post refactoring) is like this: https://brucou.github.io/documentation/graphs/real-world/rea...

So one advantage is that with those graphs, it is easier to onboard new folks arriving to the codebase. They just have to follow arrows to know what the code is doing in response to a series of inputs.

I could continue but with all that said, the Hyperapp implementation of the same application is 27Kb and also fairly simple (even if arguably not as simple) to get into. So there isn't a clear-cut ex-nihilo benefits to state machines here. In fact if you would have implemented the same application as a MPA instead of a SPA, for most, if not all of the pages, using a state machine to model the behavior is simply overkill. Most of the job and value of the machine in my example is to do the client-side routing done in the machine (so no extra library cost).

Anyways the bottom line is the tool is useful but you have to figure for what, and where is the value maximized. The obvious cases have already been figured out.

Post reply on HN