Hacker News new | past | comments | ask | show | jobs | submit login
React chaos in mid and large web apps: Any different experiences? (reddit.com)
37 points by rdsedmundo 3 months ago | hide | past | favorite | 47 comments



I've been writing React for a long time, and I loved it for the first few years. I thought ui=f(state) was brilliant. But over time I've come to realize that what I really loved was JSX, and I was merely putting up with React's rendering model so that I could use it.

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.


If you're a react developer that started in the industry in the last 4 or 5 years, I'm sorry. The web industry did a real disservice to newcomers by pushing people so heavily into learning react from day 1, potentially without ever learning HTML, CSS, or browser APIs.

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 agree with this take. I learned web dev before React was a thing, mostly using jQuery at the time. Then as jQuery was falling out of favor I spent a lot of time learning the native browser API's and honing my fundamental JS skills as I focused more time on JS development.

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.


It's one thing to complain about React causing chaos, valid, but I would like to remind everyone about the absolute trainwreck we had before. Just slightly before polyfills and opinionated frameworks. Sure, spinning up a quick JavaScript-infused html file with a jQuery CDN link was probably the fastest way to get going, but structurally, on anything larger, this was a horrendous nightmare for most projects I came across. The amount of variables that ended up window. or similar, the various slight differences of JavaScript versions/engines/browsers, the trillions of home-made everyone-does-it-their-own-way solutions to standard problems (from cookies to animations, from error handling to networking).

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.


I agree, we can't go back. And we should acknowledge how important and transformative React was for web development. It's easy to criticize in hindsight. Now our job is to come up with something better, taking what we now know that we didn't when React first came on the scene.


React doesn't define any standard ways or libraries. You can still create any sort of mess you want.


Well, React in and of itself doesn't, sure, I agree. However, if you look at React code, from the Getting started to ANY example out there, they do all have a "structure" that easily identifies it as React code and each file has an inherent structure that I can easily split up in my brain to understand what's going on. So the use of React ... comes with ... some form of often-repeated structure/patterns.


It absolutely defines a standard for what a "UI Component" is and how its behavior should be orchestrated by the APIs React provides.

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


>but I would like to remind everyone about the absolute trainwreck we had before.

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.


how are they comparable? git is still great and there is no better option


Just a quick side note not that I think you are wrong here at all just pointing it out as an FYI but there is a tool currently in development called jj or jiu-jitsu which is currently implemented on top of git but exposes a totally different cli and set of workflows which people seem to think is a huge improvement over git. It’s a cool project to keep an eye on.


Strongly recommend React-query (now Tanstack Query). ~50% of those useEffect and useState hooks are simply loading data or tracking loading states, mutation state, etc. This really improves with Tanstack Query.

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.


In my experience React codebases turn into this mess for two reasons:

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


> front-end devs don't know how to think declaratively and think in terms of state transitions instead of realizing intent

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.


We've lost a giant chunk of the lore that made desktop great, and the average developer has no idea how to begin making e.g. an undo/redo system even if they have 10 years of experience and use one everyday.

Yes, the problem is the devs. They don't even understand how applications work.


I like this perspective, I added something similar in the original post on Reddit. The problem here has to be React and not 80%+ (sample) of the software engineers that use it.


The whole argument about Angular ten years ago was the learning curve. I’m on a project now using React with Next and find the code so difficult to read or reason about.


Angular has the advantage of being opinionated. There are proscribed ways to do certain things and it’s “batteries included”. React is a much more loose and flexible tool and you’ve got to mix and match other components to have an equivalent framework. This means angular has some advantages when used by less experienced or cohesive teams. It’s easier for a react project to spiral into maintenance hell because you can mix and match tools and paradigms easily. I would expect most angular projects to be easier to understand. React puts all the consistency work on the developer.


Angular is only opinionated for a few things you can still end up with a mess of third party libraries mixed into Angular.


The organized mid to large web app DOES NOT EXIST - it is a myth, like sasquatch. In the swath of experience I've had from working small startups to massive corporations I have never seen this mythical "organized mid-to-large sized web app" nor heard of anyone speak of it.

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.


> "useEffect" [...] this function is absolutely not intuitive

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


Loved react till v15, I'm lucky enough that I moved into a strictly backend role right about when react 16 was introduced. I don't comprehend how hooks stuff is more readable. I occasionally browse the front end code in our company when trying to debug an issue, and the code just looks so un-intuitive. It's littered with `useHooks`, `useEffect`, `useMemo` and stuff.

It's night and day comparing that to our backend/backoffice written in Elixir.


What does back office mean in this context?


a tool used strictly internally


We've definitely experienced chaos when building large React apps. I don't think it's necessarily React's fault (though I'm not particularly a fan), I think the complexity is inherent in managing stage in both a client app and a server app. We've since moved to building apps with Phoenix LiveView and been much more productive. I've also built some libraries to give you the same benefits (single source of state on the server) when serving the front end in Elixir isn't an option: https://github.com/launchscout/live_state.


I find working with React and Mobx a breeze, also for complex apps. Not sure, why this has not been more widely adopted. It eliminates usually the need to use those mentioned unintuitive and error prone state handling mechanisms.


I optimized Mobx away by switching to "zustand" – it's another layer of simplification and I haven't had a project where it didn't work. Next to zero dependencies and it just "works". Mobx got me angry once they had too many breaking changes from 4 to 5 etc.


So much this. It's a perfect match for React. Let's you keep data/logic out of the components, 0 boilerplate, optimized renders (similar to what react compiler will do...).

You can even use tanstack-query to get all/most of its benefits. (by using its core package instead of react-query)


Yeah. I think mobx is often disregarded as mutable state goes against the react philosophy. Instead they somehow rather make monstrosities of codebases (redux anyone?) just to avoid it.

And mobx is really just signals everyone now loves automated via proxy objects.


My first real job was at FAANG with 2 co-technical leads with 0 reports and 3 people working with them.

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.


I don't mind how the view part of react works, but I don't like how it gets so complicated managing state. With a lot of state libraries for it now just providing lots of hooks you end up with so much in the view. Like you'll have more than half the component be hook code managing state. While I prefer functional view components, there was something said for the encapsulation class components gave you.

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.


serious question: like writing classical UI desktop UI code

Why are front end app frameworks so different from desktop GUI frameworks?


I think a big part of it is react specific which is also largely down to the functional approach which took over the community years ago.

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.


My experience:

  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.


I'm an experienced web dev, who mostly works with Vue. Sometimes I have to work on React apps.

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.


useEffect() replaces component lifecycle hooks in Vue. useRef() is the answer to this.$refs in Vue.

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.


With server components/actions you get rid of most useEffect()s and a lot of useState()s, and with the upcoming React compiler you get rid of useMemo(), useCallback(); Redux and other state management tools become pretty irrelevant for many server-component-driven apps as well.

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.


It doesn't help that React is the go-to for getting a job nowadays and most people skip over even the most basic fundamentals to just immediately learning React, without having ever understood the principles behind React or what problems it was created to solve in the first place.

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.


I've encountered all the issue listed in the post. The worst for me is redundant (overdetermined) state, that is, when a state variable is actually derivable from other state variables. It's pointless, confusing, and broadens the space of possible states, including impossible and inconsistent ones.


I see this all the time, even with coworkers who have worked with react for years and when I question it they have such a hard time understanding what the issue is with this.

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.


To be fair to React, this is 100% the developers' fault. State must be minimal, by definition.


Using HTMX after dealing react is a huge breath of fresh air for me.


[flagged]


Which options do you mean!?


vue, svelte, htmx to name a few


The trash comments are very flame-baity but the underlying assertion is true that it’s been a long time since it was “the obvious choice”.

One of the somewhat ironic things that I don’t know is well understood within the React community is that just purely by the nature of its particular architectural details, it’s only going to continue to become and worse and worse choice as time goes on.

What started as its main selling point (an abstraction over the messy parts of web standards at the time) has actually become one of its biggest liabilities.

It was fundamentally designed around solving problems that just haven’t been problems for some time now and much better options do indeed exist.

That’s to say absolutely nothing of how it has since been hijacked by a for profit VC backed company who are just making everything worse and more complicated with more lock in.

Now is a good time to start looking for the exits. I don’t think having it as the default for a new project in 2024 is a good idea either.


this comment should be detached from the flagged comment and join the bigger discussion


yeah that's pretty much what i was saying. react is trash.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: