The past two years there has been a growing dissatisfaction towards React. You can find people trying to find arguments against choosing React. I've done that too, because there are some severe issues in how we use (or don't use) React. Mostly the issues have to do with stuff like performance, search engine optimization, accessibility. It is easy to point your finger to what appears to be the "root of all evil", React.
So what are the problems with React and are there any ways we could deal with them?
The above is one of the statements which I could agree on, but not without conditions. Because the real problem here is not really React in itself!
The biggest thing one can argue against React is how it puts HTML and DOM away from sight. When looking at JSX you don't really see that much of clean HTML structure by looking at all the combinations of components. This means that to have good HTML you really have to have good component level abstraction which would allow pretty much any developer to produce mostly good semantic HTML with minimal effort. Or you'd have to setup tooling that validates HTML, and aggresively encourage using browser devtools with focus on the HTML.
And these things are a problem. First one requires there to be at least one developer who builds good component abstractions so other could just focus on building a good app. Second one means you need somebody to be aware of the need in the first place, and the time to do that and actively advocate.
To me it seems neither of the above really happens. Instead you have a lot of projects where people have chosen React because that is what everybody is using, yet the teams consist more of generalist programmers rather than many who have high HTML, CSS, web standards knowledge.
And once we have this kind of a team: how likely you think it is that they choose the best additional libraries to use? I'll throw one example that probably shouldn't have caught as much popularity as it has: CSS-in-JS.
Why I say this? Well, it limits even further the visibility and knowledge of web standards, in this case CSS. You're unlikely to learn much of CSS selector usage with CSS-in-JS, mostly you deal with just pretty basic styling. CSS-in-JS also encourages "duct tape" type of components, so when discipline is missing instead of having a good set of base components you end up with lots of style utility components.
To workaround performance issues we have thought to do intelligent code splitting, so bundles per page could be smaller. The typical end result to this is pages with something like 20+ JS bundles being loaded on first page load. Because we also thought prefetching improves performance for the next page load.
We now have tools like Lighthouse and Web Vitals to measure how this kind of setup performs, and well, it ain't pretty. It is very hard to optimize when React takes over the entire DOM.
There are also other issues with React taking over the entire DOM. A typical example is growth hacking. While I don't really like the whole concept and the current way it is being done with A/B testing that needs months of time to see any results, it is still a thing that exists and companies seem to like to do it. And the challenge here is that you need to provide places for external scripts to hook into your page. This easily gets into conflict with React having made to have the entire DOM for itself!
Growth hacking is not the only case. People may use Google Translate, or other localization tools. React controlled sites tend to break pretty bad and become unusable. For a business this can mean lost sales.
For companies with a continuous project there are a couple of things they can do to help avoid these issues from piling up. One possibility is to hire more of your own developers, and aim for having people working on your projects for longer. Give them time to learn alongside work, maybe arrange mentorship, ensure you have some devs with longer experience, and especially people who are passionate specifically about the web. Prioritize your business needs so that there aren't too many big features needing to be done at the same time.
I think all of these are very hard and not many companies can confidently cross all the boxes. Of course consultants can work fine as well, but it is harder to guarantee their longevity in a project. Many consultancy companies seem to favor rotation to ensure satisfaction with new challenges every now and then.
As for developer level one of the things is to reconsider the way React apps are written: maybe you don't need to wrap the entire HTML everywhere. Maybe you can have "widgets" instead: load React miniapp for specific feature as needed. So even if you render the whole page with React on server side, you could abandon most of universality, as that will guarantee you don't need to hydrate the entire DOM tree with React in one go. This is a very possible scenario for sites that have content focus.
Of course this kind of change is hard to accomplish. Some of you may use React frameworks like Gatsby or Next.js. So far I haven't had a look whether these frameworks can be customized this much; probably not. Luckily there is a new player on town that lets you have only as much JS as you need: Remix. It is still in beta, but it encourages existing web standards a lot more than other solutions. In the other hand it does cost money, so that can be a blocker for new devs.
To cure this: embrace HTML and CSS over JS (when it makes sense). Front-end facing code should reflect more that you're working with HTML and CSS. Accomplishing this is not an easy task, and I don't yet know how to actually successfully shift code so that even though you'd be using React, you would also bring HTML and CSS in as first-class citizens. So that even the new devs working with the code would get the idea of what is important on the browser side, that it wouldn't get lost in all the code even on a larger project.
A possible issue here is that we're breaking the "universality" of having the exact same code executing on client and server.
I guess splitting to two parts may feel like we might be doing "double the work", but I think that might be an illusion. Often the features we do for browser side are very front-end only. Some things like checkouts might not even make much sense to have with server side rendering.
At least I miss many of these on my everyday project at work.