3 ms·
The bit of react that is f(newState) => UI is the easy part. The bit that is g(state, userInput) => newState is the hard part. In particular managing the scope
by jameshart 4y ago
The bit of react that is f(newState) => UI is the easy part.
The bit that is g(state, userInput) => newState is the hard part. In particular managing the scope of that newState.
Oh, and sometimes you need to handle h(state, asynchronousData) => newState too.
And then comes the fact that even though your f is _pure_, it also has to be _fast_, because it's going to run every time you get a newState.
- metta2uall 4y agoIn my experience redux-toolkit + redux-saga for async stuff usually work really well. In case of performance problems one can go with profiling + targeted optimisations (e.g. a separate store, some locally managed state).
- acemarke 4y agoGlad to hear RTK is working well for you! FWIW, we actually specifically recommend _against_ using sagas in almost all cases. Instead, we recommend using our RTK Query API for data fetching and caching, and the RTK "listener" middleware for reactive logic: - https://redux.js.org/usage/side-effects-approaches#recommendations https://redux.js.org/usage/side-effects-approaches#recommend...
- metta2uall 4y agoThanks, I wasn't aware RTK now has a saga-like "listener" feature - will look into it! What I like about sagas are their simplicity & power (once one understands how generators & effects work), plus the eventChannel feature which lets one integrate with non-redux events. Good TypeScript support is a problem though, and I've had to resort to typed-redux-saga :/
- acemarke 4y agoYeah, we specifically designed the listener middleware to do ~90% of what you could do in sagas, but with a smaller bundle size, simpler API, and better TS support: - https://redux-toolkit.js.org/api/createListenerMiddleware https://redux-toolkit.js.org/api/createListenerMiddleware - https://blog.isquaredsoftware.com/2022/03/designing-rtk-listener-middleware/ https://blog.isquaredsoftware.com/2022/03/designing-rtk-list... Event channels was something we intentionally _didn't_ try to replicate per se, and tbh I've never tried to use those myself. (But, I _suspect_ that you might be able to do something similar with listeners even though we don't have a specific replacement built into the listener middleware, and if you do I'd love to see an example in action!) If you get a chance to try out listeners in your project, I'd definitely appreciate feedback on how well they work out for you - whether they solve your current saga use cases, what cases they _don't_ handle, anything we can do to improve the listener API, etc.
- cageface 4y agoI had to rescue a redux-saga project that went badly off the rails. It was one of the most inscrutable and difficult to debug codebases I've ever had to work with. Forget completely about ever having a usable stack trace.
- bayesian_horse 4y agoYes, I guess you can abuse every technology. Sagas are always sideeffects and thus have to be used with restraint. Sagas keep state (and you should keep most state in the redux store, anyway). So, yes, you can go wrong, as with everything else. But it's better than using useEffect as an async framework.
- bayesian_horse 4y agoYes, absolutely. Don't use useEffect as an async framework, use thunks or sagas. Remove most logic from the components into sagas,thunks and selectors. That way your components will be smaller, more testable, easier to change, easier to reason about.
- Zetice 4y agoI get so lost in these conversations, because I've been the lead on a relatively complex React app for literally years now and none of any of this has mattered or come up in any way whatsoever. Our app is plenty fast/responsive, maintenance hasn't been perfect but it's been manageable, same with new features... The learning curve around context was a bit steep but we get it now and haven't had any issues since. It's like you're speaking a different language to me, and I find that so weird considering we're using the exact same framework. How am I not having any of these issues? I'm honestly at the point where I wonder if y'all are making things harder on yourself somehow, because I could see how getting obsessed with counting every single re-render and trying to overoptimize would result in the stuff you're saying while not actually impacting perf in a meaningful way.
- anste 4y agoI've been in the same boat with these discussions. When I do encounter a component with countless re-renders as described, it is usually painfully obvious what causes them and easy enough to fix. I think we're going too far if we're expecting React, or any framework, to be fool-proof to the point that we can just throw "whatever" we want at them and expect it to have peak performance.
- mind-blight 4y agoDepends on what kind of so your building. For a while, a lot of the form libraries out there triggered huge numbers of rerenders and caused perf issues. That's still a problem, though some of it has gotten better uncontrolled components. Timing-based UIs are (such as a sequence of triggered animations) can get really messy really fast. I've seen some really messy bugs in a app that had visuals and audio tied to different timers and user inputs in the app. We eventually moved all time-based animations to observables, which helped some
- ivalm 4y ago> a lot of the form libraries out there triggered huge numbers of rerenders and caused perf issues Something I don’t quite get, doesn’t useRef just solve the re-render issue?
- MrPatan 4y agoThis is why people use redux, keep state in a store and just do v=f(state). Your app is the store, not the DOM. It really makes things much simpler. The trick is to keep all the state in the store, including when things are loading, when some user interaction is happening but not yet complete, etc. From your comment, it seems like there may be some problem if the user is interacting somehow, let's say in the middle of doing a drag and drop, and some data update comes in from a websocket, right? Well, if that's going to cause a problem for your render it's because apparently your data-updated function h needs to know if the user is doing a drag and drop. That should get put in the state when the user starts the interaction, and now h can know about it and react correctly. Yes, it's more complicated than just have some component render based on the data you receive, but that's because it turned out that your app was more complex than you thought, it has more states you need to care about. There's no magic wand, but this stuff works, just adds some boilerplate code but I don't mind.
- Izkata 4y ago> because it's going to run every time you get a newState. Didn't have to in the past. Back with class-based components we had shouldComponentUpdate(), and lost that when components switched to pure functions.