|
|
|
|
|
by Stoids
380 days ago
|
|
Most UIs I've written in my career benefit from being modeled as FSMs. While I see the value proposition of the atom-based approaches, especially for basic applications, I can't help but become a bit hesitant about their scalability long-term on large teams. Part of the reason the very dogmatic Redux approach of a event dispatching + single store of truth caught on so quickly was because a lot of us had felt the pain of two-way data binding / global state with event listeners in Angular 1. I distinctly remember the horror of debugging digest loops (scope.$$phase memories) and being completely lost in the unstructured data flow. What made for a great demo became a nightmare at scale. There's nothing stopping people from using these atom-based libraries to build more robust abstractions, but from my professional experience I tend to just see global getters and setters with useEffects / lifecycle method of your frameworks choice as a side effect sync. Maybe my instincts are off here though and I am overly cautious. I love XState but the learning curve is rather massive and getting buy in from other team members is hard when the DX of the atom approach is so nice. I feel like state "management" and reactivity performance are talked about a lot, when ultimately state orchestration is where I see things fall over the most. |
|
I’ve seen far larger messes created in redux due to tight coupling of things across large apps to a global store and the inability to work with things like Maps and Sets or other values that are not trivially JSON serializable.
In the other direction I have seen messes with observable-based state management systems where things become far more complex and too far abstracted (how often do you really care about anything other than the latest value and maybe the previous one?) or with proxy based systems that have too much fragile magic (valtio, mobx) or require wrapping your components and going all in on oop (mobx)
To me signals hit the magic spot of reactive without being overkill and keep code testable in smaller units while retaining performance benefits of surgical updates
I like xstate in theory — it’s a good way to think about complex state transitions — but in at least half of cases in practice where you aren’t interested in a derived value, someone is storing a value/ getting the latest value or toggling a boolean and it’s just such overkill for that. The reducer pattern itself doesn’t meaningfully show up much for similar reasons. The other common cases are with fetching states (idle, loading, refetching, success, error) but you often end up wanting things like cache management or maybe even optimistic updates so eventually tanstack query covers that ground better than rolling your own.