12 ms·
useStateMachine: A ½ kb state machine hook for React
- wyuenho 5y agoIsn'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 5y agoThe 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.
- wyuenho 5y agoIt'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.
- bennyg 5y agoThis 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 5y agoYes, you can. The vast majority of developers don't. That's the difference: enforcement.
- sudhirj 5y agoYeah, one can definitely build a finite state machine on an infinite state machine, that’s essentially what the library helps you do. It providers a framework to do so with some boilerplate taken care of.
- Waterluvian 5y agoI 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.
- k__ 5y agoThey fit so well into React it's crazy. But they're also soooo idiosyncratic which makes them rather ugly on a general level.
- codeflo 5y agoThey 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 5y agoAren't there proper TypeScript bindings which catch (more) cases?
- judofyr 5y agoInteresting. 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.
- isuckatcoding 5y agoSo 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 5y agoThis 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.
- DylanSp 5y agoThanks 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 5y agoOf 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.
- wilsonrocks 5y agoI'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 5y agoWe're constantly working on improving the TypeScript experience with XState; there are some new things like `createModel()` that might help!
- wilsonrocks 5y agoOooh createmodel is new to me - will check it out!
- cacozen 5y agoOh, I need to try that too!
- RobertKerans 5y agoActions 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
- runawaybottle 5y agoCan 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.
- davidkpiano 5y agoLots of good examples here: https://xstate-catalogue.com/ 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/ https://statecharts.dev/
- runawaybottle 5y agoNo, 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 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.
- davidkpiano 5y agoNobody's forcing you to use this library. Please take your negativity elsewhere. EDIT: Okay, didn't mean to interpret criticism as negativity; I apologize.
- whoevercares 5y agoHow does this work with RxJS or reactive pattern?
- cacozen 5y agoIt’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
- vikingcaffiene 5y agoIt’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 5y agoFinite 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 5y agoI 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.
- skrebbel 5y agolove the logo
- cacozen 5y agoHahaha, reused from a video on my YouTube channel, was created in 5 minutes on Apple Keynote
- deleted 5y ago[deleted]
- yewenjie 5y agoIs there quick primer on what and why of state machines?
- cacozen 5y agoAuthor here. Yes, I made a series of videos about it, starting here: https://youtu.be/N0OaRdJuVlc https://youtu.be/N0OaRdJuVlc
- lloydatkinson 5y agoAs 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 5y agoIf 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.
- lloydatkinson 5y agoNo, your disingenuous disregard is not helpful. FSM is literally the name of it. Not all FSM's store extra data, that is only a recent concept from things like xstate.
- nsonha 5y agowhy does this need to be a hook?