React chaos in mid and large web apps: Any different experiences?
old.reddit.com
old.reddit.com
As I see it, React has the following problems:
1. The web is inherently imperative. Using things like setTimeout or autofocus is a real pain with React.
2. The state of your application is orthogonal to the structure of your UI, and coupling the two causes a ton of headaches.
3. React takes complete control over your UI, so adding UI plugins usually requires specific integrations. The google maps SDK comes to mind.
4. By taking complete control over the rendering process, React creates a barrier between you and the DOM. You stop thinking about the web platform, and you start "thinking in React." This degrades your quality as a professional engineer and causes your platform expertise to deteriorate over time.Do yourself a favor and learn the platform if you jumped right into react. When react inevitably loses favor and the jobs dry up, you'll have a much easier time when you know the underlying platform and better understand why react does what it does.
Don't take the above as some claim that react is already dying, it could still have plenty of time left. It's just inevitable that it will eventually die and web development jobs will move on to something else.
I see a HUGE difference in fundamental understanding of sometimes even the most basic web dev fundamentals between people who learnt just starting with React from the get-go and people who did not. Its sad that people jump to using React from the start just to get a job at the cost of never learning these basic skills that used to be basically required knowledge for web development, and many never go on to get a deeper understanding.
I like it more, than I liked it in the past. It's uncool to say that, but I was so happy to see structure in the world of JavaScript.
What it doesn't provide is a way to manage complex state that persists beyond the scope of one component (Context isn't good enough), and every single app has state that persists beyond the scope of one component
That isn't good enough. People make the same argument about Git. "But it was so much worse before Git".
React was a useful step forward for its time, but it's not a great solution now.
Even better is to get Tanstack Query for free with type-safe backend in T3 stack.
Hard to overstate how much the symptoms described in this thread can improve simply from this.
- front-end devs don't know how to think declaratively and think in terms of state transitions instead of realizing intent
- back-end devs build a classic REST-like API which provides zero affordances to drive a proper reactive front-end.
React-query is a good solution to the wrong problem. It's basically an elaborate and ornate footgun that allows you to stretch guess-based cache invalidation to its limits. Each piece of data has to be tagged with front-end only query keys, and cache invalidation requires you to re-implement and repeat your business logic optimistically in all the individual `onMutate` and `onSettled` handlers.
The actual problem to be solved is how to reliably sync data to a front-end and mutate it safely. Doing this well requires you to architect your data so it is syncable in the first place. You should separate sources of truth from derived data, you should use uniform APIs for CRUD manipulation, you should probably version your records, you should express mutations as universal patches, and so on.
Cache invalidation should only require substituting one globally addressable record with another one, and/or telling the front-end to refetch it from the source. If you are doing complex data surgery or traversals, you're doing it wrong, because that's what the reactive rendering is supposed to do for you. Anything else is a trap for juniors.
There is a thing among park rangers where “if people are taking this shortcut despite the signs and fences, then it’s the trail that’s wrong, not the people”.
More software engs should think this way instead of “educating harder should solve incompetence”.
It’s not that people are incompetent. The trail is wrong.
Yes, the problem is the devs. They don't even understand how applications work.
There will ALWAYS be cruft, and doubly so in a webapp since what is essentially the "build target" is always moving, heck the language it runs on is always moving.
The title of the post might as well be, "has anyone else worked in a mid to large sized web app code base?". The experience is ubiquitous and has nothing to do with React specifically. In fact the problems that the author mentions, "Large component files with excessive composability" for example, is easily overcome with the exceptional tooling that now exists in the JavaScript/TypeScript ecosystem - of course one might not realize the huge strides that have been taken here if they've only been doing web dev for a couple years.
Anecdotally - I really don't like to see Reddit posts pop up on HN, it degrades the quality of this site towards Reddit's level.
100%. I've found `useEffect` is an effective foot-shotgun, even I still blast away some toes with it. What makes it some weird to me from the start (React 16.8, ~2019) is how they folded several, clearly named, lifecycle methods into this one callback. The motivation for this change [1] informs me that maybe I've just never worked on Facebook-scale front-ends or I've just forgotten the pain of explicitly having to write all those methods, but I rather liked their separation.
[1]: https://legacy.reactjs.org/docs/hooks-intro.html#complex-com...
It's night and day comparing that to our backend/backoffice written in Elixir.
You can even use tanstack-query to get all/most of its benefits. (by using its core package instead of react-query)
And mobx is really just signals everyone now loves automated via proxy objects.
They were iOS-specific, and called in to lead (and I was hired) after a sprint where not-iOS people had built an iOS app. It was pretty good!
The problem was, their heads had inflated so much that they had ascended to the heavens in terms of self-proclaimed computer scientist.
So they wasted months and months rewriting the app to have a Redux implementation in Objective-C, 4 years after Swift came out, and pitched it as a final solution to making the app reliable and dev velocity fast, as compared to that horrid codebase they had to inherit.
The relaunched app took 18 months, was missing features, had a 2/3 higher crash rate. And the core problem, network reliability, came down to them acting like the networking code was some prized expert-level thing only they could manage...but the issue was they re-implemented TCP and were blocking ACK packets on frame rendering. So it'd be really fast and normal then hit the ack queue limit, and only be able to send one packet every ~16 ms.
Just thinking out loud because it's very funny to find out Redux also ended up being too much in the JS community, and I hadn't heard till now.
But hey, our managers managers manager really liked that one video of that one stilted live replay the initial 6 months in demo could do.
We've got our own state framework for react that adds controller classes: it makes it easier to write imperative code, but with ours for the business logic rather than the view. It works a lot like mobx but class based. https://github.com/aha-app/mvc unfortunately we haven't put as much love into the oss library as we should have. We use it extensively in our apps.
I find it makes writing react code much more like writing classical UI desktop UI code, with wired up controllers and models.
Why are front end app frameworks so different from desktop GUI frameworks?
That ends up with a very different set of patterns and whatnot compared to lots of various desktop approaches.
Something more traditional desktop looking might be Angular, Lit or Futter which to be fair is actually a desktop and mobile framework that also happens to target web.
If you’re looking for an interesting journey into what that looks like in practice I would suggest doing a couple of flutter tutorials and building a todo app or something. It’s very different looking from React for sure.
1. Hooks and functional components were supposed to save us, but has made react harder to use in large codebases because most developers don’t use React as intended. A lot of foot guns because most JS devs don’t try really understand closures. I remembered way less problems and bad practices in the componentDidMount days.
2. React demos well for small apps, but its un-opinionated nature means there is no standard for large codebases that need to load remote data and manage shared global state. No one likes redux or any other de facto solution. React needs to come with batteries included, or at least strong opinions on how to manage large codebases.Skimming through the list of sins, pretty much all of them look like things I do on a regular basis. I do not understand React. I find it pretty much incomprehensible, incredibly complicated, and overly complicated for what it does.
I can't really described what `useEffect()` does, only that it's a solution I use when other things don't work. I can't tell you when I should use `useRef()` rather than state or props.
I never have any of these issues in Vue. Its conceptual model has always been pretty easy to grasp, although it got messier in Vue 3 since they tried to copy React more.
Agreed that Vue and React are very different flavors. I think Vue has a shallower learning curve. In spite of React's problems, I do feel it scales to larger apps a little better than Vue. Both are great solutions.
But I agree that React attracts a lot of mediocre and inexperienced programmers, and does not provide very much guard rails against doing bad things, so predictably the average code quality is terrible.
Any developer who I work with who started off just learning React is notably lacking in understanding and skill at webdev when compared to those who did not just jump straight to React.
Not using derived state or in other words not using the minimal state required is one of the most common issues I end up seeing, people just add state everywhere not realizing a lot of the time additional state is not needed and every little variable doesn't need to be separate state.