0xfffafaCrash 4 days ago

React doesn’t really concern itself with state management. Of course it has context, state, and props but the mental model for it predates focus on fine grained reactivity in frontends — useSyncExternalStore helps enable others to fill that void in v17+. Fine grained reactivity was notably also missed in the development of web components — only now is there a tc39 proposal for signals (in its early stages).

Jotai, mentioned briefly in the article, may not be built in but is as intuitive as signals get and isn’t even tied to React as of later versions.

I’ve very rarely met a state management problem in clientside state management where neither tanstack query (for io related state) nor jotai (for everything else) are the best answer technically speaking. The rare exceptions are usually best served by xstate if you want to model things with FSMs or with zustand if you actually need a reducer pattern. There’s a tiny niche where redux makes sense (you want to log all state transitions or use rewind or are heavily leaning on its devtools) but it was the first to get popular and retains relevance due to the fact that everyone has used it.

You can go a long way with useContext and useReducer/useState but few would opt for alternatives if jotai came batteries included with react.

3
90s_dev 4 days ago

Never heard of Signals[1] until now, thanks. But it makes me nervous with how much influence it has from React and Vue, and the way React and Vue do things. These are not the be all end all methods of reactivity, and I can't help but think if there's going to be an official language feature implemented for this, there needs to be room for other voices to be heard that have zero influence from React/Vue. Maybe there's still time since it's Stage 1.

[1] https://github.com/tc39/proposal-signals

0xfffafaCrash 4 days ago

I wouldn’t say signals is coming from React. If anything React is the latest to the party and being dragged there reluctantly by where the tech community is going. They’ve mostly been resisting the movement towards signals because it undermines a lot of the arguments they have made for their virtual dom, synthetic event system, and rerender all the things dogma. Solidjs is much much more in the signals camp. Angular, Vue, Svelte, etc also recognize the need for this sort of reactivity.

React could be argued to have abandoned the fight for being the best client side framework technically (though they have dominance pragmatically). They are really all focused on Vercel’s Nextjs/SSR/SSG/RSC stuff in recent years

dleeftink 4 days ago

Also shoutout to Solid's inspiration, S.js[0].

[0]: https://github.com/adamhaile/S

mock-possum 4 days ago

I remember Signals from my actionscript days

jazzypants 4 days ago

Just FYI, Signals are actually derived from Observables in KnockoutJS. React was originally created as a response to the first wave of JavaScript Frameworks which heavily relied on two-way binding-- remember the whole emphasis on "unidirectional flow"?

Signals recently became more popular as people observed the performance and DX that they made possible in SolidJS. Solid's creator, Ryan Carniato, has acted as a bit of an evangelist for them-- even working closely with the Angular team.

jazzypants 4 days ago

Whoops, this sentence accidentally got left out as I was moving it around for formatting:

"Preact, Qwik, Svelte, and Angular all quickly followed suit and unlocked huge performance benefits."

uallo 4 days ago

From your own link:

> The current draft is based on design input from the authors/maintainers of Angular, Bubble, Ember, FAST, MobX, Preact, Qwik, RxJS, Solid, Starbeam, Svelte, Vue, Wiz, and more…

What other voices would you like to get feedback from?

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

0xfffafaCrash 4 days ago

I haven’t ever seen issues scaling with jotai even on very large apps working with extremely complex data structures.

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.

Stoids 4 days ago

As someone who created those horrifying RxJS monstrosities, I agree with most of this, which is why I caveated my concerns. Tanstack Query simplified a lot of these issues—separating server state and caching from client side state was a huge boost. I’m mostly coming from the perspective of someone who just inherited a Jotai code base with 200+ atoms and trying to wrap my head around it. Any library poorly used can lead to a mess though, so not going to claim it’s a problem inherent to all atom based approaches.

davidkpiano 4 days ago

Re: atoms + learning curve, this is why XState Store exists, which supports both XState-style state updates and atoms: https://stately.ai/docs/xstate-store

I also like the approach of Svelte, and realize that sometimes a full state machine isn't needed. I don't think that atoms should be used everywhere, since updating state freely without guardrails just leads to disaster long-term.

nateroling 4 days ago

Fine-grained reactivity (ie Knockout) was a thing well before React. If anything, React was a response to the deficiencies of fine-grained reactivity.