32 ms·
The new wave of React state management
- deleted 4y ago[deleted]
- ARandomerDude 4y agoThis is one reason I like to use ClojureScript + Reagent for React(Native) development. Clojure atoms make a perfect in app db, that can hold anything, have good performance, and lots of "batteries included" functionality for reading and writing nested data.
- m_ke 4y agoMobx solved all of the state problems properly a long time ago.
- pweissbrod 4y agoAgreed! I'm surprised at the comprehensive work going into researching the history of state management in this article while completely missing MobX. What problem does MobX not already solve?
- jitl 4y agoAll cited frameworks solve the problems. Article is more of a survey. It’s a pity to miss Mobx while discussing proxy/mutation API in Valtio.
- tommoor 4y agocame here to say the same thing.
- Chris_Newton 4y agoWhat problem does MobX not already solve? I’d say the two biggest hazards with the reactive/declarative style are cyclic dependencies in the data model and remembering history. Tools like MobX let you write quite elegant code in the right circumstances but they are less helpful if, for example, you have a complicated set of constraints and the effects of changing one value in your state can propagate in different directions depending on what first changed to start the cascade. This style also tends to emphasise observing the current state of the system, so if you need a history as well (for undo, syncing with other user actions via a server, etc.) then you probably have to write a whole extra layer on top, which is more work with this kind of architecture than for example if you are using a persistent data structure and reducer-style updates (as popularised by Redux within the React ecosystem).
- tomduncalf 4y agoThis is a really great explanation - I love MobX in many ways but the “observing the current state of the system” definitely has its downsides, which you’ve expressed very clearly!
- TN1ck 4y agoFor a project that was basically an after effect like application I needed a history, but also very fast updates, settled with mobx-state-tree which gave me a way to preserve history. Worked great for that application, no regrets. So there are some solutions available if normal mobx is not enough.
- phaedryx 4y agoThat's actually what converted me to Vue. I did all of the Redux stuff, but then found Mobx and enjoyed that so much more. A friend of my told me "if you like React + Mobx you'd probably like Vue" (I think he was quoting from the Vue website). He was right.
- jetako 4y agoShoutout to MobX-state-tree
- speedgoose 4y agoIt is a lot slower though, I had to migrate from it to normal mobx to come back to descent performance when having a few thousand objects.
- tomduncalf 4y agoSeconded, I looked at using MST a few years ago for a React Native app with frequent (30hz maybe) state updates and the CPU hit compared to plain MobX was too much
- kabes 4y agoMobx has made me finally appreciate frontend programming again. It's like people want to deal with the insanity that is redux only because it's a more pure functional style which react seems to promote.
- Rapzid 4y agoSomething I like to point out to teams when it's the case, and it's often the case, is "When is the last time anyone on the team has used time travel debugging? Never?".
- acemarke 4y agoDepends on what you mean here specifically :) I'll agree that the Redux DevTools "skip action" and "jump back to action" features are not all that commonly used in practice. I _maintain_ Redux, and I don't even use them that often. On the other hand, the ability to see a written list of all dispatched action type names is valuable by itself. So is the ability to click one of the listed actions and see the action contents, state diff, and final state. _That_ is very powerful. Beyond that... I now work at a company called Replay ( https://replay.io https://replay.io ), and we're building a true "time traveling debugger" for JS. Our app is meant to help simplify debugging scenarios by making it easy to record, reproduce and investigate your code. The basic idea of Replay: Use our special browser to make a recording of your app, load the recording in our debugger, and you can pause at any point in the recording. In fact, you can add print statements to any line of code, and it will show you what it would have printed every time that line of code ran! From there, you can jump to any of those print statement hits, and do typical step debugging and inspection of variables. So, it's the best of both worlds - you can use print statements and step debugging, together, at any point in time in the recording. Additionally, because Replay records the browser's OS calls, it captures _everything_ that happens in the page. That means you can debug _any_ website or JS app, no matter what framework it uses - React, Vue, Angular, Svelte, jQuery, or vanilla JS. I actually recently implemented a POC version of support for the Redux DevTools in our Replay debugging app, so that if you do record a Redux app (or Jotai, or Zustand, or NgRx), you can use that same Redux DevTools UI to see the action history. So, yes, time travel debugging _is_ an amazingly powerful concept. It's just ironic that that particular aspect of Redux didn't end up getting used that much... but the Redux DevTools themselves are still valuable, and Replay is actually a far superior "time travel debugger" overall.
- pier25 4y agoYeah when using React (or Inferno, etc) I default to Mobx. If you like that model, Svelte stores are very close to that as they are really reactive primitives. Honestly I think it was a terrible idea to call them stores. SolidJS is also built on this idea of using reactive primitives. In this regard it's even better than Svelte as you get true fine grained reactivity.
- nwh5jg56df 4y agoJust what the world needed
- petilon 4y agoThe "state management problem" appears to be an invention of React. This didn't use to be a problem with MVC. The state lives on the server. When state changes it should be persisted on the server immediately (in case the user unexpectedly closes the browser). On the client all you need is a cache. With MVC, each page is more or less independent. Each page gets the data it needs from the server (through a client-side cache), then updates the server when something changes. No "state management problem". In contrast, ReactRouter sees the entire application as one humungous component. Therein lies the problem.
- jitl 4y agoI came to understand MVC (model-view-controller) from writing Objective-C desktop software (https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/MVC.html https://developer.apple.com/library/archive/documentation/Ge...). The “M” in that MVC is “Model”, which is the same idea as “state management”. It’s an object that stores state and notifies listeners when it changes. You can think of these libraries as ways to implement the “Model” concern in the application. But from your use of MVC, I think you are referring to server-side MVC, where the “V” is a rendered HTML template? I’m not sure how to square the desktop software version of MVC with your assertion that state should only exist on the server. My Cocoa desktop apps ran fine 10 years ago without a server. The React application I work on today has many bits of local state it needs to track like “what is selected?”, “how wide is the sidebar?”, and “should this menu be open?”. I don’t think the server should be involved in such matters.
- petilon 4y agoI am talking about client-side MVC. Models should be POJO [1], no library needed. [1] https://en.wikipedia.org/wiki/Plain_old_Java_object https://en.wikipedia.org/wiki/Plain_old_Java_object
- wilde 4y agoThis is true until your customers complain that your UI is super slow. You realize they’re trying to use your app from a cell phone with poor service. So you have the genius idea to add optimistic updates in JS. Now you have all the problems from the article since you need to update all the components everywhere on screen that share state.
- fabian2k 4y agoFor me the issue of state management mostly went away after starting to use React Query. It turned out that the most problematic state was server-side state for me, which is handled very well by libraries built for that purpose. The state that remains is often simple enough that plain old React state management with useState/useReducer is sufficient. A lot of state can be local, and local state is easy to handle with the built-in tools of React. And global state is only really an issue if it changes often. For mostly static state like information about the current user, theme or UI settings and similar kinds of state using React Context works perfectly fine. Of course this depends heavily on the kind of web application you write, if your application is closer to Photoshop in the browser than a simple CRUD app you probably can make good use of more complex state management libraries.
- kasane 4y agoThis matches my experience as well. Additionally, React Query has support for features like retries and caching.
- celim307 4y agoReact query is one of the highest quality react libraries I’ve ever used
- bernawil 4y agoThe state that remains is often simple enough that plain old React state management with useState/useReducer is sufficient hah this is an understatement. For hooks, the React runtime already does a ton of non-standard-js things under the hood. useState gives a method to update and "subscribes" a component to updates on the hook's value. Put that code in a custom hook, export it and you re-invented Redux. In fact, exporting a single big useReducer for all your state gives you something almost identical to old style Redux.
- acemarke 4y agoFWIW, there _are_ a number of technical and conceptual differences between Context+`useReducer` and Redux. I wrote an extensive post describing those differences and potential use cases for each: https://blog.isquaredsoftware.com/2021/01/context-redux-differences/ https://blog.isquaredsoftware.com/2021/01/context-redux-diff...
- deleted 4y ago[deleted]
- Waterluvian 4y agoI used Redux and loved it until I moved to typescript. Then there was a terrible amount of boilerplate and magic. So I wrote my own 75 line alternative that does a bare minimum. It’s basically just a useContext wrapper. And I haven’t looked back since. This is for pure client side stuff, of course.
- acemarke 4y agoHi, I'm a Redux maintainer. FWIW, we specifically designed our official Redux Toolkit package to not only eliminate the general concerns about Redux "boilerplate" [0] [1], but also work great with TS. With our recommended RTK+TS usage patterns, a typical "slice reducer" file only needs to define a type for the reducer's state, and then define a case reducer as `(state, action: PayloadAction<MyData>`) [2], and that's it. We've put a _lot_ of work into making sure that our library TS types minimize the amount of types that you have to write in your own app code. Also, one of the reasons we now teach the React-Redux hooks API as default is that it's drastically easier to use the hooks with TS than the legacy `connect` API. If you haven't had a chance to see what "modern Redux" looks like, I'd suggest going through our docs tutorials to see how we want people to learn and use Redux today [3] [0] https://redux.js.org/introduction/why-rtk-is-redux-today https://redux.js.org/introduction/why-rtk-is-redux-today [1] https://blog.isquaredsoftware.com/2022/06/presentations-modern-redux-rtk/ https://blog.isquaredsoftware.com/2022/06/presentations-mode... [2] https://redux.js.org/tutorials/typescript-quick-start https://redux.js.org/tutorials/typescript-quick-start [3] https://redux.js.org/tutorials/index https://redux.js.org/tutorials/index
- Waterluvian 4y agoHooks made react and redux far less ridiculous. Class based react and redux wss maddening. I’ll poke again but last time I tried I couldn’t avoid Typesafe Actions library.
- acemarke 4y agoYeah, _please_ don't use `typesafe-actions` :) It may have had some value before RTK came out, but a lot of the opinions and approaches shown in its docs lead you to write _wayyyy_ too much code. For example, we specifically recommend _against_ writing TS unions for action object types [0]. RTK completely obsoletes `typesafe-actions`, and the TS usage patterns that we teach today should result in a pretty minimal set of types that you need to write in your own code. For a small example see the RTK+TS template for Create-React-App [1]. If you want to see what a real app codebase can look like, the client app for my day job at Replay.io is OSS [2]. It's admittedly a somewhat messy codebase due to its long evolution and legacy (started as the FF DevTools codebase, copy-pasted, and we've been slowly migrating to RTK+TS and modernizing it), but files like [3] show how I would write a real slice reducer with RTK+TS. [0] https://redux.js.org/usage/usage-with-typescript#avoid-action-type-unions https://redux.js.org/usage/usage-with-typescript#avoid-actio... [1] https://github.com/reduxjs/cra-template-redux-typescript https://github.com/reduxjs/cra-template-redux-typescript [2] https://github.com/replayio/devtools https://github.com/replayio/devtools [3] https://github.com/replayio/devtools/blob/454804188d33900a269a426b6166a86b83ad3221/src/devtools/client/debugger/src/reducers/breakpoints.ts https://github.com/replayio/devtools/blob/454804188d33900a26...
- jeroenhd 4y agoI've used Redux but I've never heard of any of these alternatives. I have no doubt they're popular, but what is it about frontend that makes everyone reinvent the wheel every five years? Everything from the tooling to the tiny details somehow expires and gets recreated in a similar-but-not-similar-enough way that keeps the ecosystem in a constant state of flux. Is it the lack of platform API support? Is it the community trying to make everyone a library developer? What's wrong with frontend?
- etimberg 4y agoI think it's because redux is quite painful to use with very modern apps. Most of the time you need something like `redux-saga` or `redux-thunk` to deal with async side effects. I'm not sure which is the most popular today, but sagas are based on generators and trying to use those with typescript is very very painful and the underlying issue [1] is marked as a design limitation in TS itself. In addition, if you want to have your app load as smaller chunks rather than a single large bundle, you need to be careful to ensure that things work even all the backing reducers aren't yet loaded. 1. https://github.com/microsoft/TypeScript/issues/32523 https://github.com/microsoft/TypeScript/issues/32523
- doodlesdev 4y agoIn my experience the experience with Redux Toolkit is awesome, it's essentially an opinionated way to use Redux for modern web applications and I believe they really hit the mark when it comes to reducing boilerplate and the need for extra deps. Although I'm still not a big fan and prefer to use built-in tools of React to manage state when possible (now that we have Context, Suspense, etc.)
- geraldwhen 4y agoYou need redux saga because api interactions can be complex. I need to update a remote resource. But wait! Sometimes that can fail. I need to capture the failure logic and make appropriate ui changes. There are 4 types of errors and they require doing some library logic to figure out what to display. But wait! I want to wait 250ms before triggering any state updates, or else the ui transitions will feel buggy. Oh, and product now wants to make sure we capture some random third party tracking event in between specific state changes. The ui MUST NOT change until the tracking call succeeds. This and more is trivial in redux saga, and you can write tests around it.
- melony 4y agoMost of these new client side state management libraries are incompatible with any form of SSR. If you see the documentation for Jotai/Zustand/Valtio, the solution is to avoid using with Next.js at all, or fall back to hacks using context+provider at which point the state manager becomes effectively redundant.
- rebelos 4y agoIsn’t SSR only really relevant when you need to optimize for SEO (which only applies to a subset of apps)? Seems like it doesn’t confer any other significant benefit.
- azemetre 4y agoThink about how the benefits to SEO (page speed, web vitals, less client work) can improve overall app performance. SSR is just one technique.
- purplerabbit 4y agoI'm sorry people are downvoting, because you are correct. SSR (by which I mean Next.js) is the most over-invested in JS tech of all time. It introduces a bunch of crummy DX which never pays for itself from a business standpoint. SSR is only potentially useful for landing pages. In which case you should be using Wordpress or something like Wordpress so you aren't wasting dev resources on something a marketing team should be doing. (If your argument is that SSR is necessary for speed, I'm pretty sure exporting your Wordpress site to static HTML + CSS and using Cloudflare could more than make up for the difference.) The one asterisk I'll add to this is that SSR in the form of the Remix framework may justify its own existence as it removes the need for an explicit API layer, which lets you skip a ton of boilerplate code. This is a big win. The fact that Remix uses SSR is just an implementation detail -- it's the DX that's actually valuable (although SSR fetishists will probably still like it, too.)
- melony 4y agoAnd how exactly do you plan to avoid the flash of white without SSar?
- dageshi 4y agoAfter reading the "Grug Developer" article recently, I've been thinking of frontend development as "The Plane of Eternal Complexity Demons".
- jitl 4y agoThis is because UI programming is inherently extremely complex, especially compared to something like a stateless API tier running in AWS. It’s stateful software deployed to countless different runtimes on hardware you don’t control. Instead of a smattering of API routes handling well-structured semantic datatypes like `POST /burgers?pickles=false`, input comes in the form of arbitrary UI events from various input devices like pens, keyboards, mice, etc that must be interpreted to have a semantic meaning. Often there are hundreds of API routes (event handling elements) on screen at once in a complex application. UI engineers are perpetually frustrated by this complexity, and so some small percentage look for better ways to handle these issues. Of course it’s best to avoid UI programming entirely, but in many domains it’s necessary.
- nwh5jg56df 4y agoWe went to the moon some +50 years ago. We ought to have solved "UI programming" already, no? Something is not working
- agumonkey 4y agosimple problems easily becomes complex in mainstream contexts.. due to bazaar like soil. NASA had to solve one immensely hard problem but they owned the context. Vertical integration if you will.
- syspec 4y agoBy that logo , SpaceX shouldn't exist.
- bobthepanda 4y agoUltimately, successful products are determined by customers and by product managers and their executives, and it turns out there is no one-size-fits-all approach to even basic UI programming because everyone has an opinion. Not to mention, as an example touch became a widespread new UI paradigm in the last 10-20 years.
- hellohowareu 4y ago[flagged]
- arcturus17 4y ago> never heard of tools These libs are at 4.7k, 8.9k and 17.1k stars on GitHub... > discuss the deep inner workings of things The article is a few thousand words and there are a few interesting reflections... > of things that already exist The point of the article is to actually talk about "new wave stuff"... You are arguably incorrect on many fronts, but more importantly, did you have to spend this many words being an utter dick to the author?
- UmbertoNoEco 4y agoOr you just manage state in the server. With https://inertiajs.com/ https://inertiajs.com/ you can even afford to not to declare an API and still manage the state back there.
- ramesh31 4y ago>Or you just manage state in the server. With https://inertiajs.com/ https://inertiajs.com/ you can even afford to not to declare an API and still manage the state back there. Then we can party like it's 1999!
- UmbertoNoEco 4y agoAs God has always intended
- monkaiju 4y agoReally surprised there was no mention on MobX. I've used int for lots of projects and loved it.
- doodlesdev 4y agoI'm pretty sad this is the point we are at with React frontend development, the library is becoming much larger than it's original scope and it's getting bloated while not solving the essential problems that happen. In my opinion the best solution we have right now for frontend JS development is to not use JS or JSX at all and instead use a DSL such as Svelte, this way the compiler abstracts all complication and there is no application bundle size bloat. Obviously we have Preact (which solves react-dom bloat), MobX (which solves state management), etc. which are all great tools but the problem is that every tech stack is different and the more the core technology can do without getting more bloated the easier it is to introduce new developers to a codebase and keep up with changes.
- nine_k 4y agoSvelte does wonders to code size, indeed. But does it solve the problem of growing state which never gets GC'd when components which used to use it are gone? Does it solve the problem of only redrawing the required minimum (beside the normal VDOM approach)? I'm asking as someone not knowledgeable enough about Svelte.
- doodlesdev 4y ago> Does it solve the problem of only redrawing the required minimum (beside the normal VDOM approach)? Yes, in fact I think it's actually pretty hard _not_ to redraw the bare minimum LOL. If you want to know more about Svelte (even if you're not looking to develop with it) I HIGHLY recommend listening to this presentation called "Rethinking reactivity" by Rich Harris (the creator) https://youtu.be/AdNJ3fydeao https://youtu.be/AdNJ3fydeao > But does it solve the problem of growing state which never gets GC'd when components which used to use it are gone? I think the answer to the question is yes. Although the problem I'm speaking mostly about state management is the source of truth problem. Svelte provides a global store to store data, and data stored on local components are just _variables_ (no useState or hooks or anything complicated) where the Svelte compiler handles everything. Something else I'm really eyeing right now is SolidJS which takes a very similar approach to Svelte (compiler instead of library) for frontend development but provides an API that's very familiar to React developers so there's not much of a learning curve (although Svelte has a very easy learning curve too).
- abxytg 4y agoI've been running into nasty performance with setRecoilState and large piece of state firing multiple times per frame.
- kizer 4y ago"Prop drilling". So many buzzwords. SSR, Hydration, Tree shaking, Hot module reload. How has web development gotten here? It just seems to have evolved so much needless complexity to me. Don't forget about web components! Integrated into the platform.
- cercatrova 4y agoI've often found those that complain about these buzzwords are the people who do not actually do any frontend engineering. There are buzzwords in every language and every library. It's not an indictment of complexity (which exists outside of any one language or library), it is simply the terms of the trade of that particular technology.
- kizer 4y agoI don't know why but front-end terminology always makes me cringe. I know it's useful jargon. I don't know why I have a visceral distaste for them. Maybe because it feels like taking a small, simple thing and making it seem like it's something more. But you're right. I haven't done much front-end at large scales. Only at one employer for a short while.
- cercatrova 4y ago> Maybe because it feels like taking a small, simple thing and making it seem like it's something more. Perhaps it makes more sense to treat frontend engineering as thick client desktop development of yore. Websites are no longer small, simple things, they are now the primary apps that many people use (through the broswer and especially through Electron), so there needs to be sufficient tooling around managing that complexity.
- kizer 4y agoYou’re right. That makes sense. I’ve been out of web dev for about 4 years so I’m just reactionary now I guess.
- 4y ago
- nikodunk 4y agoFor anyone struggling with the complexity and boilerplate of Redux, at my day job we added Redux Toolkit (the newly recommended add-on by the Redux project itself!) and it solves most of the verbosity issues! We use it to share all our state logic over mobile and web and it works excellently now. I'd actually recommend Redux w/ Redux-Toolkit, for the first time ever.
- phreack 4y agoThere's a library called rematch that's been implementing most of these ideas for a long time, but sadly it didn't get popular enough and it seems to be somewhat lacking maintenance. It was such a pleasure to use (in comparison) that I just can't believe how people ever work with those massive switch statements.
- acemarke 4y agoOne of the reasons we created Redux Toolkit was to eliminate the need to write those switch statements :) (also action type strings, action creators, object spreads, having to split logic for one feature across multiple files, and all the other "boilerplate" concerns that users rightfully complained about over the years.) - https://redux.js.org/tutorials/fundamentals/part-8-modern-redux#using-createslice https://redux.js.org/tutorials/fundamentals/part-8-modern-re... - https://redux.js.org/tutorials/essentials/part-2-app-structure#creating-slice-reducers-and-actions https://redux.js.org/tutorials/essentials/part-2-app-structu... - https://blog.isquaredsoftware.com/2022/06/presentations-modern-redux-rtk/ https://blog.isquaredsoftware.com/2022/06/presentations-mode...
- wereHamster 4y agoWeird that XState was not mentioned.
- aarpmcgee 4y agoAgree. I am working on a side-project and using XState for local state management, and Jotai (with Immer) to send that state to various components in my app. It is working really well and mitigating unnecessary rerenders. More moving parts than I might like, but they play together nicely and I haven't hit a single wall yet.
- johtso 4y agoFor me using xstate was a game changer. Pulling logic out into a state machine gives you so much clarity over your application logic. Also nice to have your business logic defined with something that is framework agnostic.
- nine_k 4y agoYes! An explicit state machine is my desire for the UI development since the Delphi days of 1990s. It makes things so much more observable and sane. Redux nudges you to build that state machine by hand, in the form of the reducers folder, around the centralized state. While elucidating, it's still a lot of boilerplate (which you can sort of factor out), and it's still not one clearly laid out entity.
- acemarke 4y agoFun fact: one of the XState devs did a proof-of-concept showing how to use XState state machines as Redux reducers and integrate the side effects handling as a middleware: https://github.com/mattpocock/redux-xstate-poc https://github.com/mattpocock/redux-xstate-poc We'd like to work together to turn that into a more official integration sometime soon.
- aarpmcgee 4y agoThis looks excellent. I see a lot of potential in the idea of combining the strengths of RTK(+Query) and XState. Thank you for sharing!
- acemarke 4y agoYeah, if you've got any particular use cases or ideas for how you'd like to use them, please put up a discussion thread in the RTK repo and let's talk!
- ramesh31 4y agoOnce you see the light of state machine based UI's, it's immediately obvious and you never want to go back. The problem comes in convincing others to deal with the boilerplate. It's worth it, but it never really sinks in until you use it.
- ramesh31 4y agoI'm just tired of the redundant reinvention of new "terms" for literally everything in JS. I don't want to know what an "atom" or a "proxy" or a "thunk" is. These are meaningless abstractions that simplify down to a store and a callback. Stop inventing terms to make yourself feel smart.
- acemarke 4y agoFWIW, the term "thunk" is a long-standing CS term that long predates Redux [0] [1] [2]. In fact, my first job back in 2008 involved a C++-based emulator/VM framework, and the devs used "thunk" to refer to jumping from the original program binary out to altered/replacement code written as C++ to add additional behavior or replace functionality. "Proxy" is also a long-standing term as well that describes wrapping or replacing functionality of a system, which is why it's used for HTTP servers and why it got used for a new JS capability in the ES2015 language spec. [0] https://en.wikipedia.org/wiki/Thunk https://en.wikipedia.org/wiki/Thunk [1] https://stackoverflow.com/questions/2641489/what-is-a-thunk https://stackoverflow.com/questions/2641489/what-is-a-thunk [2] https://devblogs.microsoft.com/oldnewthing/20081020-00/?p=20523 https://devblogs.microsoft.com/oldnewthing/20081020-00/?p=20...
- mechanicum 4y agoAnd “atom” comes from Clojure’s atomically updatable state. [0] [1] [0] https://clojure.org/reference/atoms https://clojure.org/reference/atoms [1] https://news.ycombinator.com/item?id=23183385 https://news.ycombinator.com/item?id=23183385
- proxyon 4y agoYou are literally complaining about Computer Science
- deleted 4y ago[deleted]
- civilized 4y agoCurious layman here (no web dev experience). I thought the main selling point of reactive programming was that it abstracted away the need to manage state. What problems, then, does a state management library solve in a reactive framework?
- tadfisher 4y agoReactive programming provides the capability to react to changes in state. You still need to hold that state somewhere, mutate the state from your reactive code, and control the lifetime/scope of that state. Managing state becomes more of a concern with reactive programming, but it also becomes very explicit; this is something that traditional MVC approaches try to hide, to the detriment of anyone trying to understand the data path of your application.
- wruza 4y agoELI5 why Excel can update all of the sheets from all the different data sources without overloading its user with “state management” thing and React can not?
- azemetre 4y agoThis talk from Rich Harris should answer most of your Qs: Rethinking reactivity https://www.youtube.com/watch?v=AdNJ3fydeao https://www.youtube.com/watch?v=AdNJ3fydeao He goes over the history of spreadsheets, reactive programming, and dunks on react.
- deleted 4y ago[deleted]
- wruza 4y agoI was negative in my deleted comment, but watched the video anyway (I remember skimming through it back in 2019). It answers my question only tangentially, because it doesn’t touch state management per se. The key point was, what’s the fuss about React SM and why it must be explicit in it. The video basically says that it is a nonsense which may and should be avoided. I agree, and so still don’t get what ggp is talking about.
- sebmellen 4y agoFor anyone who has not had the pleasure of working with these simpler “atom-based” state management libraries, I would implore you to try Jotai (https://jotai.org/ https://jotai.org/), which is mentioned in the article. Jotai’s atomic model and ease of use has made writing complex React applications far more joyful for me.
- rochak 4y agoHas React become too big for people to not consider other alternatives? I used to be a big React advocate but realised that it is getting too bloated with every new release. Have been looking into Svelte and it is turning out to be a breath of fresh air compared to whatever React is culminating to be.
- matthewwolfe 4y agoI think it’s exactly the opposite as you describe. The React API has been incredibly stable and consistent for years now.
- sakerbos 4y agoI've advocated for Redux in many commercial projects because I knew that it worked well at scale. There was occasional pushback due to the large amount of boilerplate code involved (actions, reducers, sagas, models/interfaces if using Typescript) but the team mostly settled on Redux because it was the best supported and most widely used state management framework at the time. IMO the larger pool of devs that understand a framework, the better a project's chances are of success mainly because the industry has a high turnover of developers and it's easier to find replacements to maintain the existing code. That being said, I'm now a huge fan of react-query.
- Yhippa 4y agoQuestion for you since you seem knowledgeable about React state management. When I did a lot of back-end programming in Java we frequently coded to interfaces where we could swap out back-end implementations for ORM for example if needed. There's an ongoing joke where nobody actually did that. Is there something like that in React? My understanding is that there's a lot of coming and going of state management frameworks, and it would seem to me committing to thr API methods of a particular framework would be risky. Or am I thinking at the wrong abstraction level?
- acemarke 4y agoTo some extent, this was the purpose of the "container/presentational" pattern that was popular for a few years [0]. By splitting your components into "containers", which were responsible for managing data fetching, and "presentational" components, which just received data as props and displayed the UI, in theory you could swap out the state layer someday without having to alter most of the display handling. But, the community really began over-obsessing about that, and often treated it as a rule you _had_ to follow (to the point of people seeming to panic and asking for help about whether a particular component should live in a `/containers` folder, `/components`, or somewhere else). Dan Abramov, who wrote the article that helped really popularize that approach, later updated it to say he no longer finds it very useful. In addition, React hooks push you towards a very different approach, where each component is now responsible for calling the hooks that it relies on for data fetching. That hook may still abstract where the data actually comes from, but the calls are now part of the component itself. I talked about this change in approach in a blog post and conference talk conference talk [1] [2]. Finally, the testing approaches in the ecosystem have changed as well. Instead of "shallow rendering" components using the Enzyme library, the community has moved on towards more "integration"-style tests with React Testing Library. This does require more setup work in tests to ensure you have all the various data providers wrapping the components under tests, and real or mock data being loaded, but the tests themselves become simpler and any state library usage becomes basically irrelevant to the actual test implementation. See [3] and [4] for some thoughts on that. Soooo... yes, you _can_ write more abstraction layers, split your components by "containers", and even add DI via React context or some other purpose-built library if you want to. You could even abstract out all the UI components you use from a particular library just in case you end up swapping date pickers or something. But as always, it's a question of whether that will actually provide a benefit, now or in the future. And in general, most React apps do not bother with those extra abstractions. [0] https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0 https://medium.com/@dan_abramov/smart-and-dumb-components-7c... [1] https://blog.isquaredsoftware.com/2019/07/blogged-answers-thoughts-on-hooks/ https://blog.isquaredsoftware.com/2019/07/blogged-answers-th... [2] https://blog.isquaredsoftware.com/2019/09/presentation-hooks-hocs-tradeoffs/ https://blog.isquaredsoftware.com/2019/09/presentation-hooks... [3] https://kentcdodds.com/blog/testing-implementation-details https://kentcdodds.com/blog/testing-implementation-details [4] https://blog.isquaredsoftware.com/2021/06/the-evolution-of-redux-testing-approaches/ https://blog.isquaredsoftware.com/2021/06/the-evolution-of-r...
- jfvinueza 4y agoI've been using Pullstate for medium-sized apps for a couple years and it's fantastic: uses Immer under the hood (so it's all immutable even if it look as it wasn't), it's API and mental model are vulgarly simple, and my impression is that it's quite performant. I also like that the store is disentangled from the component tree, which allows for plenty of flexibility. Totally recommended! https://lostpebble.github.io/pullstate/ https://lostpebble.github.io/pullstate/
- sdrinf 4y agoUsing pullstate in production for a number of apps now; seconding this recommendation. Almost all of the complexity / mental overhead / boilerplate mentioned in this thread mostly goes away with pullstate.
- windowshopping 4y agoI'd like to share my approach to React state management, because after a decent amount of industry experience I've stumbled onto a solution I find to be very excellent. Firstly, I use the open source library Pullstate[1], which I find to be as effective as any alternative but _far, far_ simpler to understand and use. All my components are functional components. For any state that _only_ that component needs, of course I simply use the useState hook. When things need to be shared among multiple components, I create a Pullstate store - for instance, for an app I'm working on now I have a UiStateStore like so: type UiStateStore = { isSidebarOpen: boolean; // etc }; export const uiStateStore = new Store<UiStateStore>({ isSidebarOpen: false, }); Then, in the components that need to know if the sidebar is open, I import this store and use its state hook _the exact same as the normal useState hook_, like so: const isSidebarOpen = uiStateStore.useState(s => s.isSidebarOpen); You simply pick which properties you need off the state object ("s"). When you open the sidebar, you simply update the store like so: onClick={() => { uiStateStore.update(s => { s.isSidebarOpen = true; }) }} And automatically, any components using uiStateStore.useState and watching the isSidebarOpen property will get updated, exactly the same as the normal useState hook - just shared. It's so dead simple and has made complex app-building so much easier for me. By comparison, Redux in my experience has a harder learning curve with a lot of unnecessary pieces and boilerplate - it seems crazy to me that people think it's a great solution and it feels like people have convinced themselves all those pieces are "necessary", where in my experience they are anything but. The one caveat is that if I have a component with many handlers, e.g. onClick, onMouseMove, onContextMenu, onMouseLeave, etc (and in some cases I do), components can get bloated. I haven't found a fix to that yet. But that's more an inherent issue with react than anything to do with state management. [1] https://github.com/lostpebble/pullstate https://github.com/lostpebble/pullstate
- etimberg 4y agoIn some ways this feels a lot like http://alt.js.org/ http://alt.js.org/
- have_faith 4y agoYou might like the atomic state management libraries mentioned in the article, they simplify things to another level because they sort of remove the concept of a store entirely. For example in Recoil I would do this: export const isSidebarOpenAtom = atom({key: 'isSidebarOpen', default: false}); And in the component: (it mimics useState) const [isSidebarOpen, setIsSidebarOpen] = useRecoilState(isSidebarOpenAtom); and later... setIsSidebarOpen(true) Recoil will then re-render any component that relies on isSidebarOpen. The only real boilerplate is having to specify keys for each atom, which I find a small price to pay for such simple global state.
- cosmiccatnap 4y agoI find it interesting that across a decade and countless frameworks from jQuery, meteor, angular, and now react the core problem is still and somehow progressively worse than ever...state. I find it strange this is still such a hard problem to solve in an environment with a slew of options for key value global, local, and remote storage
- bayesian_horse 4y agoIt's easier to solve it than to agree on what is the solution and to keep it. The more alternatives to redux there are, the higher the chance you get thrown into projects with some lesser known framework, maybe not even used to its best.
- memonkey 4y agoAbsolutely great article. One thing I always see missing is why front-end applications can't use sessionStorage or localStorage? Why is this generally frowned upon?
- wizofaus 4y agoI'd assume because it's often abused? There are perfectly legitimate reasons to use either and I've been technical lead on React projects where the decision was made to use them. In at least one case it was a known "shortcut" as we didn't have time to properly develop server-side persistence and local storage was "good enough" for 95% of use cases. And session storage is needed to allow page refreshes without cookies.
- bayesian_horse 4y agoFor what purpose? If you use it as state management inside the SPA, it's actually slower than all the other approaches.
- frosted-flakes 4y agoMost apps actually do use localStorage as a persist layer. But it's not a replacement for state libraries because it's just a place to store strings, and that's it. A state management library is so much more than a scratchpad.
- wildrhythms 4y agoWhat these state management solutions usually attempt to address is reactivity. When the <UserLoginModal /> finishes its login process and sends a bunch of data about the newly logged-in user to the global store, I'd like for some N other components in the tree to consume that new information. State management solutions help relay that new information down the tree to the components that need it. Local storage and session storage can persist data, but have no way of informing components that something has changed without implementing a setState() and listener/callback system, at which point you've recreated yet another state management system.
- proxyon 4y agoThe same reason we read from RAM / CPU cache and not from the hard drive
- DonHopkins 4y ago>For example with local UI state, prop drilling both data and methods to update that data often becomes a probably relatively quickly as things grow. Can anyone parse that sentence please? Was this article written by GPT-3?
- andrewljohnson 4y agoprobably->problem is a typo, and prop drilling is lingo for digging down a large chain of components I think.
- rpeden 4y agoProp drilling in this context is just passing both state and update function(s) for that state into a component via its props.
- glenjamin 4y agoI find it very disappointing that this article does not attempt to draw a distinction between state management for complex local states (imagine an image editor), or state management for fetching and updating data via APIs I think the shape of solution needed for these two problems are quite different.
- lloydatkinson 4y agoSame here. Local state and server state are not always the same. I see a lot of people saying how replacing redux with react query worked well and that’s great but there’s definitely times when you have a lot of state in a client side heavy SPA. The distinction should really be highlighted more.
- gloryjulio 4y agoExactly. I think people who complains about complexity of some of the tools, just have not worked on the complex webapp(not the webpage) before. Unfortunately these 2 always get conflated.
- valand 4y agoThose are conflated because on complex webapp developers own the problems with state management, sequencing of methods, concurrency, caching, queueing, categorizing actors, etc. The developers in this set would understand the need to separate these things because they often have to customize it and state management are often not suitable for customization. Meanwhile, most developers don't need to have customized actions sequence. Therefore they can just pick one state management for them to delegate these stuffs.
- gloryjulio 4y agoYeah. But web developers need to understand, broadly speaking there are 2 very distinct use cases. They NEED to scope whether they are making a webapp which could even be comparable to a native app, or a webpage which is just dealing with some async requests. That's not the tools' fault.
- weeksie 4y agoThe problem with redux is that it's a simple, extremely powerful tool for creating a CQRS architecture on the front end but very few people treat it that way. Instead they bolt on things like rtk and add yet another layer of abstraction over their project. In those cases it's almost always better to just use something small and simple like Zustand, which the article called out. For bigger projects, custom middleware is where the magic is. If you don't understand redux well enough to write your own middleware (it's not very complex, it's just under documented for some reason) then it's better to use one of the other, simpler abstractions instead of adding one abstraction (redux) then piling on more abstractions to make it usable.
- acemarke 4y agoPretty sure you and I debated "vanilla Redux" vs RTK in a thread a couple years ago, but I'll link my most recent explanations of why RTK is the right way to use Redux today: - https://redux.js.org/introduction/why-rtk-is-redux-today https://redux.js.org/introduction/why-rtk-is-redux-today - https://blog.isquaredsoftware.com/2022/06/presentations-modern-redux-rtk/ https://blog.isquaredsoftware.com/2022/06/presentations-mode... Also, note that RTK has a new "listener" middleware that simplifies the process of "run this code when some action is dispatched". You can certainly still write a completely custom middleware if you _want_ to, but the listener middleware handles that work for you.
- weeksie 4y agoI get it, you're _really_ invested in RTK but man, I just find it to be the right answer to the wrong question. Since we last talked I have worked on projects where rtk was used because the devs didn't really grok redux and so far that's the best use case I've run across. That said, now when I run across situations like that I tend to guide clients to simpler state management solutions instead of piling on another layer of abstraction.
- mikewhy 4y agoHave you considered something like "selector based side effects"? https://github.com/mikew/redux-easy-mode#selector-based-side-effects https://github.com/mikew/redux-easy-mode#selector-based-side.... The difference is most side effects are based around when an action is dispatched, but I wanted to know when things _change_. It's possible to do the same thing with a react component + useEffect, but I thought a pure-redux solution would better fit the spirit of Redux.
- ezekiel11 4y agoI ditched React/Redux for Vue 3 & Pinia and my god, what a world of a difference. Everything is intuitive and I am not googling days to fix tooling issues, or having to do it the React/Redux way which was honestly overly engineered and non-productive. Frontend shouldn't be complicated and we've been lied to, you are not Facebook, you don't have billions to throw at engineering, you must pick the path of list resistance
- 42e6e8c8-f7b8-4 4y agoI believe the worst part is redux. React is mostly reasonable. Redux is massive boilerplate.
- firtoz 4y agoI switched to zustand from redux and I am loving it.
- theteapot 4y ago> I believe the worst part is redux .. And hooks. Sorry but React started to go crazy when hooks IMHO.
- aliswe 4y agoTo me, this is where React started to make sense ...
- lifeplusplus 4y agoI had a project where state was coming through redux, from parents via props, context somewhere from parent elements, xhr fetch/graphql, local storage... Debugging was hell. I've always hated hooks, they replaced easy and clear lifecycle functions and rely on magic to work, literally don't function like regular js functions but look like regular functions
- KronisLV 4y ago> Debugging was hell. I've always hated hooks, they replaced easy and clear lifecycle functions and rely on magic to work, literally don't function like regular js functions but look like regular functions You know, with how hooks work in Vue, things seem be easier to understand and get started with. Though at least with React I've had plenty of projects end up with render loops that are hard to debug because of how everything is written. So much so, that I wrote a blog post about it a while back "Modern React is broken": https://blog.kronis.dev/everything%20is%20broken/modern-react-is-broken https://blog.kronis.dev/everything%20is%20broken/modern-reac... Personally I wish that we could already have some tooling that'd tell you something along the lines of: Render loop detected! The following chain of calls was responsible for it: A -> B -> C -> A -> B -> ... Please check the useEffect hook on line X, which has the following items in its dependency array which changed: [Y, Z]
- bayesian_horse 4y agoI didn't get the memo apparently. I still think Redux+Thunks+Selectors+Sagas is great and that combination solves all my problems. Boilerplate isn't negligible but relatively tame. There's a straightforward way how to model state, and I don't have to put too much logic (especially async) into components. But that's just me...
- chrisco255 4y agoYeah I've always thought the complaints about boilerplate were misguided. Whatever the cost in boilerplate implementation was more than made up for by having predictable, deterministic UI output. That being said, I think hooks did open up the state management design space quite a bit and classic redux style state management doesn't quite line up with it. Still totally valid as an architecture, though, in my opinion.
- acemarke 4y agoEh, as maintainer, I'd say the complaints about "boilerplate" were generally pretty accurate :) As I've talked about in a couple posts and presentations [0] [1], there's a distinction between "inherent" and "incidental" complexity. Dispatching actions and using reducers is "inherent" - it's part of Redux, and you can't remove that because then it's not Redux. But things like writing `const ADD_TODO = "ADD_TODO"`, object spreads, etc, aren't _necessary_ for using Redux - they're inherent complexity. Which is why we wrote Redux Toolkit to fix all that incidental complexity :) Redux still won't ever be as few lines of code as various other libs, but writing Redux code today is much simpler than it was previously... and yes, the _benefits_ of Redux (predictable code, debugging, separation of state updates, middleware) are still entirely valuable. [0] https://blog.isquaredsoftware.com/2022/06/presentations-modern-redux-rtk/ https://blog.isquaredsoftware.com/2022/06/presentations-mode... [1] https://blog.isquaredsoftware.com/2019/10/redux-toolkit-1.0/ https://blog.isquaredsoftware.com/2019/10/redux-toolkit-1.0/
- shroompasta 4y agoZustand is a lot more popular than the comments or the article implies. I see it quite heavily used amongst Netflix engineers. That being said, prop drilling was made more of an issue than it really is, especially considering the boilerplate needed for state management libraries like Redux. But if there does need to be a global store, I usually reach for zustand as the API is probably the easiest out of the ones mentioned.
- todd3834 4y agoI’ve been using redux ever since it came out and a home rolled flux architecture before that. I gotta say I’ve been using zustand lately and it feels so effortless compared to other solutions. I couldn’t imagine going back to redux. Although redux slices feel a little bit closer.
- ashishb 4y agoAfaik, Vue ships with batteries included.
- meling 4y agoI’ve not seen overmindjs mentioned on hacker news. We use it in our React app and my students who wrote the code liked it a lot… maybe others have advanced enough by now to be on par with or better than overmindjs. https://overmindjs.org/ https://overmindjs.org/
- russellpekala 4y agoI do find redux super helpful for undo/redo (as mentioned in the article) and have not found a similar library for another state management solution that can do quite what I need there.
- wruza 4y agoYou probably know it, but a friendly reminder: undo is just a callback doing a backwards operation, in an array named “undo stack”.
- LAC-Tech 4y agoI think the obsession the react space has with "state management" is a by-product of how incredibly convoluted reacts rendering is. The other reason is a lack of exposure to how other technologies for GUIs have handled state for decades. Maybe look outside the react bubble and see how many of these "issues" just disappear when you stop acting like react is some fundamental particle of the web.
- wruza 4y agoThis doesn’t work, the most sound comparison web developers can usually do is to jquery (speaking out of previous thread experiences, lots of them). I also see all this movement as digging more steps into the same pit they’re in, in hope that it would make a ladder out somehow. For two decades of building various business UIs on various platforms I’ve never felt that it was hard or error-prone at the level which could bother anyone to fix once and for all with some funny legs above head technique. But now it suddenly (well, gradually) became a thing everyone’s suffocating without.
- Kaze404 4y agoReact is at its core a state management library, not a UI framework. Of course people are obsessed with state management in that space.
- nyanpasu64 4y agoFrankly I feel state management is a difficult task on desktop apps as well, to the point that tracking spaghetti-shaped causation and control flow is beyond my mental abilities. Qt itself as well as many apps are rife with redundantly calculating state or redrawing GUIs when changing the same value multiple times, or changing two values which both affect an outcome (my StateTransaction pattern mostly alleviates this issue with a set of dirty bitflags and recomputing all state dependent on those bits, though the reactivity system is currently hard-coded and statically dispatched, and generalizes poorly to open-ended state or managing the local state of many dialogs of the same type). And one of the craziest errors caused by witnessing malformed intermediate values is https://github.com/Dn-Programming-Core-Management/Dn-FamiTracker/pull/148 https://github.com/Dn-Programming-Core-Management/Dn-FamiTra..., where a sloppily-written "load document" function redrew the UI in the middle of mutating document state, causing the GUI to crash after observing a broken invariant. It saddens me that so much of research in developing better state management techniques is in such a bloated and dependency-laden environment as JavaScript on the web. I like QML's reactivity system, but its evaluation engine is JS-based, dynamically-typed, and dynamically-scoped, and the UI engine itself is a buggy mess. And GTK4's list APIs promise to be better than the clusterfuck of Qt Widgets/Quick's QAbstractItem{Model/View} system (which abstracts poorly over list/column/tree collections, and widget-internal, cross-widget, and cross-application drag-and-drop), but I haven't tried that either.
- Kiro 4y agoI just run force update on the root component 60 times a second and import the global state in every component that needs data from the store.
- yulaow 4y agoThink of the user having a number of games running in parallel equal to the usual number of tabs you have open in the browsers.
- Kiro 4y ago(Sorry, I edited my comment and removed the game reference and optimization question before I saw your comment.) I mean, sure but the DOM is not even a factor compared to the actual WebGL rendering going on. The DOM is only used for UI, menus and things like that. So the bottleneck would still not be React or how I handle state.
- wruza 4y agoYou may consider using some “schedule re-render everything at the next animation frame after an event” type of library instead.
- tunesmith 4y agoI still find the whole subject so frustrating. Being a backend developer that has since out of necessity had to transfer to being a frontend-architect for a team of confused React developers, I'm struck with how the momentum of frontend development quickly leads to very complex state machines. Backend development hasn't tended to require this - you query information, perhaps you transform it, you return it. But with frontend state machines, you've got things that feel like global state sitting all over the place. If the logged-in user is this or that and/or the component state is this or that then do this unless that, and if this part of the component changes/re-renders to be that, then refigure the entire state all over again so this or that can be adjusted if necessary... I mean, I get it, basically any GUI is going to have matters like this. And I get that the idea is to work really hard to limit the contract of each sub-component so that it can feel pure and only be dependent on a limited number of parameters/properties coming in. After all, on the backend it's also easy for a bad programmer to write a function/method that accepts forty parameters and has horrendously complex logic inside. But in practice, something about the product cycle and the feature cycle of React just makes it so easy to turn into a huge snarl really fast. I feel like I'm battling against the tide. Maybe it's just something specific to our team and I need everyone to just freeze until we get some better practices in place.
- dqpb 4y ago> Backend development hasn't tended to require this - you query information, perhaps you transform it, you return it. Maybe the backend of a crud app is fundamentally simpler than a user-facing UI.
- tunesmith 4y agoThat is one possible explanation, sure. But more than inherent complexity, it's also about whether there are sufficient guardrails and best practices in place to help manage that complexity.
- erikpukinskis 4y agoI’ll add to this, there are tough problems that we solve on the front end that the backend could solve, but backend developers run scared from. For example: most backends will let you query arbitrary data, but they won’t alert you when that query changes. So we solve this on the frontend (often laboriously, with spaghetti). IMO backend developers are often unwilling to do anything beyond CRUD… and specifically they are often unwilling to model the dynamics of a domain. They want to treat the domain as frozen in a moment of time. In general, I would love to see more backend developers be more ambitious about trying to see which jobs the frontend is doing that could be solved on the backend. I think that could distribute some of the workload more evenly, and give BE devs a taste of what that higher level of complexity looks like. Sometimes I think backend developers just write off hard problems that they could solve because “that’s a frontend concern”. It’s an easy excuse.
- zmmmmm 4y agoI find the whole state management situation pretty frustrating. It seems like everybody agrees that you should only introduce tools like Redux and Vuex when you actually need it, but what I observe is that nearly everybody reflexively reaches for these tools regardless of whether they need them. I see single page applications with 5 pieces of state, fully engineered with Redux. Then the outcome is that about 50% of the beauty of reactive development is lost because the whole point was that your UI representation became isomorphic with your state. In doing that a whole class of bugs went away. Then we inject state management and suddenly all those bugs are back again, living in layers and layers of boilerplate code generated to satisfy the patterns required by the state management code. tldr; the whole reason I started using a reactive UI framework was to eliminate complexity. When you bring it back in any form then you destroyed the main value proposition.
- nsonha 4y agoIt's annoying that they now reinvent yet another old thing (proxy based dependency tracking). This seems to be a pattern in the React community. These libraries are great but they offer nothing new comparing to mobx, which started even before redux became ridiculously popular.
- himujjal 4y agoThis whole discussion and article are useless if you use Svelte. That's it. Stores and local state is THE feature that Svelte makes it easy to use.
- 5350-uiop-1130 4y agoI remember there being about 5 layers of abstraction to using Redux. Every time you change something have to update 5 or 6 files. It really gave me Angular 1 vibes. One thing I learnt from all these JS libraries and Node is that nothing is for free. If it seems too easy, then something gonna bite you in the ass down the line.
- slorber 4y agoI read the whole article, and I found it quite interesting and it has a lot of good references that I've encountered in the past (for example Zombie Children etc...) However I find it very difficult to read: there's so much text and not many example to illustrate.
- SZJX 4y agoFeedback for the author (who seems to have also made the submission): The content is good, but there are too many basic typos and grammatical mistakes in the article, making it really hard to follow at times. Not sure if it was written in another language in the first place. Please run your article through some spellchecker and grammar checker the next time, not to mention finding somebody to proofread it.