React is fundamentally bad technology. I know there are historical reasons for the virtual dom but the reasons that justified it don't exist anymore. If you want to do anything interesting with react that involves interacting directly with browser APIs you need to deal with these absurd use effect hoops to initiate state with references to dom nodes.
I've worked on 4 large react code bases and they always devolve into these blobs of non-deterministic async state with unpredictable performance.
I actually like JSX and the component model so I just use solid-js which is everything I like about react but with effortless performance and you can actually get away with never using effects so your code can actually be deterministic.
> they always devolve into these blobs of non-deterministic async state with unpredictable performance
Exact same experience here. I've been banging this drum for years. When hooks came around I thought they might make it better, but alas, we are still in a downwards spiral. Building web apps is 10x more complicated today than it was ten years ago, with nothing to show for it.
I'm happy to see some known voices in the community realizing this, but also sad that this is how things work now. The rise and fall of React will have been both a product of social media / developer celebrities.
What else have you personally had experience with? Angular would not be in my list of better alternatives.
My comparison is always with Svelte / Vue, and also what we had in previous eras (Backbone, Knockout, etc). HTMx is picking up steam too. We used to push out interactive UI in days/weeks, and mind you, in the past websites did not look all the same. There were no component libraries to start from. Today it seems most React projects are planned in months/quarters despite being built atop a mountain of third-party code, all meant to 'speed things up'.
What we do today is not faster at all, too much time is wasted on tooling and issues that arise from React's architecture (hooks, ssr, data loading, error handling, async issues, black-box performance issues, dependency hell).
Which is not at all how it works in practice. In a large React codebase you have state scattered throughout contexts, GraphQL caches and complex hook dependency trees.
Throw in SSR and component memoization and you really have no idea what caused a UI change to occur.
I've worked in many react codebases, some great some not, and the main predictor of the quality tends to be both the dev lead knowledge, the experience of the team and the learning vs churn out features culture. Same thing used to happen with jQuery BTW, only it was a lot easier to shoot yourself on the foot back then.
I feel like "X new library/framework's code is a mess" is the new "People don't want to work anymore" trope (that older workers have been saying for over 100 years).
Coming from the assumption that Facebook should have tons of experienced people using React, their implementation on Facebook.com just plainly sucks after 7+ years. The UI is slow, breaks back button navigation often, loads completely different views in case a tab goes into background and gets reloaded (I have multiple tabs open from FB Groups that interested me, many of them default to opening my Home feed or the Groups main page after a background reload).
If Facebook.com cannot get it right, who actually can?
"No True Scotsman" is also a trope going on for > 100 years, yet you are appealing to it.
Technology ages, I remember liking React a lot way back in the day. Things improve and circumstances change. Things like the virtual dom are just not needed anymore and I just want my frontend code to be deterministic, it's not like I'm writing a distributed system, it's a client ui. So calling React "fundamentally bad" is harsh but I think given the state of the world today it's true.
> the dev lead knowledge, the experience of the team and the learning vs churn out features culture
This could be said of any team using any technology. If the team is better at using it, and they are provided more time to use it properly, then they'll make a better product. That's not unique to React.
React sucks because its scope creep makes it difficult to maintain, and there's a pretty low ceiling for the end user's experience. Yes, better teams can make better products with React than worse teams, but that doesn't mean that either end product is any good.
Alongside the work on server components, they also deprecated Create React App, which was previously the official way to create new apps for development, and which had pretty good ergonomics. However, you won't find that documented on the actual CRA site - when you go looking for why your dependencies are out of date, you'll find references in obscure GitHub issues: https://github.com/reactjs/react.dev/pull/5487#issuecomment-...
As much as I like the React team and appreciate their willingness to try things (and hooks have grown on me a little), they are human, and I think some of the decisions and direction they've taken things is a mistake.
I was part of the team who deliberated on the decision to use React over Vue in WordPress, and one of the reasons for my personal preference towards React was that it embraced JS rather than inventing a whole bunch of new things - yes, there was the funky syntax of JSX, but aside from that all the statements were regular JS, and it was much easier to conceptually understand than learning a new language. Hooks started taking us away from that, with weird functions that magically encapsulate state, and things like suspense and server components have strayed further from the light.
Making things like Next the official pathway to getting started with React is great and all for people building Node SPAs, but there's a whole wide world of software outside of that bubble, and I hope the React team peers out a little more often.
I'm not even sure what the deal is with suspense and the massive wait on it. They make it sound like it's some super advanced functionality you should never have to touch(because framework! so we'll not even tell you how to use it).. Yet Vue has had async component mounting forever and it just works. And it's so easy to understand they even explain it to you; you just return a promise that resolves to a component.
Totally agree with your point about node backends. So much of the world doesn't and is not going to have their backend entirely or partially on node. But to the authors point, Vercel is Reacts daddy now and daddy needs to sell some hosting(for a new pair of shoes).
But they pretty much snubbed Vite because it's not a "framework".
Similar to how Tanstack Query doesn't even mention MobX as a state management library. It's crazy how many people use MobX for beefy apps(even Microsoft use it) but how little attention it gets.
I've mostly worked on apps(vs websites or however you want to make the distinction) so I keep appreciating being able to model the FE domain outside the view libraries with MobX.
It works with Vue, React, Solid, and nothing. So it's there for me and allows for multi-view-library pages backed by the same stores.. Niche, but clutch for certain extensible apps.
That may be the case, but the communication on the changes is terrible. I only noticed CRA was even deprecated after needing to dive deep into upgrading a dependency, and eventually stumbling over the GH issue comment.
Like the original article, I’m just kind of annoyed at React about this. There’s probably great reasons to change (albeit, I don’t really think even that comment communicates them well), but it’s annoying.
> it’s not clear/an easily understandable mental model for most people
That's already the case, thanks to hooks. Hooks are weird, and should not be taught to junior programmers because it will confuse them for the rest of their careers. Hooks are weird because it doesn't align with functional programming paradigm or with OOP paradigm... it is a new paradigm and it is like nothing else.
I'll never understand the "hooks are bad" people. I don't find useEffect confusing, creating custom hooks is a breeze, life is so much better than old class components.
When I read complaints about hooks I'm either missing something fundamental about why they're bad, or the people complaining are missing it.
Some people find the mental model to be very confusing. I've been writing hooks for years so intuitively, the behavior has sunk in. But I still admit that it's mind bending to try and understand how it actually works. The original commenter is absolutely correct that it diverges from both functional and OOP, and while that's not necessarily a bad thing, it's reasonable for people to consider it a net negative.
There was an article I read, maybe 3-ish years ago, that explained it very well. It had you actually build a hook from scratch (not a custom hook, like actually implementing hook-like behavior into JavaScript). It was great. I just tried looking it up but couldn't find it, if anyone knows what I'm talking about please link here.
Any chance it was https://pomb.us/build-your-own-react/? You can't really have hooks without building an entire framework, because the framework has to have the preserve the execution context between renderings.
"useEffect" itself is not what is confusing. What's confusing is when you have many dozens of components with effects all loading state asynchronously. Some of them might even be executing callbacks passed as props from parent components. Oh, and then those effects sometimes re-execute when the effects of parent components complete and pass down updated props! It actually reminds me of programming VHDL.
The problem is you literally need to use effects to make api requests or access browser apis. You can't get away from it. Maybe you can try and tame the complexity by centralizing this logic as a small team but if the team gets big enough it's fruitless.
Isn't useSyncExternalStore the recommended hook for API requests? And for making API requests I think most people recommend using a library. React-query, RTK or swr for example.
For accessing browser apis useEffects are the way to go, but those are usually extremely easy to understand in my experience. Or just use a library that provides the needed functionality.
You're right, but I haven't touched a React project in ages that wasn't using a fetch library of some kind that give you hooks.
Cause you're inevitably gonna want to track loading state, error state, refetch on error, revalidate etc etc.
swr or tanstack-query are great and remove the need for useEffects for API requests. For sure they come with their own overhead, but there isn't getting away from the complexity of handling API requests and all the possible paths that can happen.
> The problem is you literally need to use effects to make api requests
No. Wtf? Don't do that. Never do that. Effects are for legacy DOM manipulation (and ad-hoc use of browser apis). Pretty much nothing else. Who tampers with states and data in useEffect is hellbent on creating spaghetti.
I assume your suggestion here is just to embrace a framework for data fetching and try not to think too hard about how they in turn implement it?
Can't really fault developers for falling into this useEffect trap when even the official docs show that data fetching is indeed handled via useEffect[1], while at the same trying to yell at the reader to "NOT TRY THIS AT HOME" and just go use a framework because it's such a complex problem... which naturally just creates more questions than answers for the poor developer trying to understand how it all works.
Uhh... That's terrible piece of docs. They don't even cancel stale fetches, just ignore the recieved responses. They don't debounce anything.
There are so many things about syncing data between the client and the server that this section of the docs should just say "Don't", use Apollo or Redux or whetever. React is UI library, for data you need data library or at least general state handling library. Quick and dirty will bite you tenfold.
If you have dozens of components with dozens of uncontrolled side effects executing in unpredictable order, then nothing is going to help you until you get those effects under control. It'll still be bad architecture with or without hooks.
> It'll still be bad architecture with or without hooks
The companies I've worked with had hundreds of engineers contributing to the react codebases and people are just trying to crank out features by the deadline. I'd rather just work with tools that don't require the usage of such obvious footguns. You can code solid-js and svelte and never use effects (even though they do offer them unfortunately).
> Hundreds of developers all doing their own thing sounds like a recipe for said bad architecture
This is the how the majority of tech companies operate.
> but I know better than to single out the tool for every judgment on design.
I disagree, most react developers are not even aware of this massive foot gun. I do blame tools for problems that are completely avoided by other tools, we can just consider this a difference in philosophy but I prefer to use tools that make as many types of mistakes impossible as they can.
From my experience (picked up react when it came out) hooks are not objectively better than class components in a standard web app. In the more reactive scenarios hooks are great, and your app is already complex and in its own world of mental models.
Hooks enable complex patterns too easily and I think this causes a lot of breakdown in what would otherwise be simple applications.
As someone who was into higher order components but left front end work before hooks were a thing, I’m wondering how the programming experiences are different are different between the two. It seems to me like more or less the same thing but hooks have more magic? Is it just a syntactic difference or are hooks a paradigm shift even further than HOC?
I agree. Up until Hooks, you could make your own toy React pretty easily if you wanted to - creating a basic, unoptimised version took a few hours. That made the whole system pretty understandable, especially for junior developers - obviously, you'd always pick the battle-hardened, optimised real React for anything serious.
Hooks fundamentally altered the contract about the API that React provided, and suddenly magic was popping up everywhere. Thankfully suspense never really caught on, because that was even more magical.
I do quite like the developer ergonomics of hooks, but it does make me wonder about whether there was a world in which we could have had both the ergonomics _and_ something less magical.
(Aside: that Medium article is available to members only.)
But all the lifecycle methods were magic that needed to be understood... hooks just let you co-locate related logic in one place instead of scattered across 3 or 4 lifecycle methods.
I disagree that they were magic - you could build a test renderer for yourself and see pretty easily how they'd work. The system as a whole was understandable, and it fit into an existing mental model: you implement this interface, and React will call your methods. The specifics of how and when it did were part of the system on the other side of the interface.
Hooks on the other hand are functions that you call, which implicitly rely on a magic global state and context, and you cannot use them like other JS functions. You can't conditionally call them or change the order of them, because they contain a unique ID based on call order, which is Spooky (and is why React has to build its own ESLint rules to make sure you don't mess it up!).
Don't get me wrong - I do think the ergonomics of hooks are a lot better, but I think at least part of that is due to it being a newer iteration of the API.
They are no more just functions than require() was a function.
They use subset of function syntax to provide unique functionality. That's all.
JS was full of such things already. Functions that are hooks (in traditional sense of the word) into some platform provided functionality. setTimeout(), fetch api, promise chains, jquery. You could say that all of those are just functions but you still need to learn what each does separately to get behavior you want. JS is not Lisp where a function means just one thing used always the same way with same restrictions. JS uses functions to construct idioms that introduce functionalities foreign to the core language. React hooks are just one such idiom. You may still argue that introducing yet another idiom is unnecessary burden. I personally like them very much. Component classes were imho very bad conceptual fit for react with a lot of intricate lifecycle methods and special fields. Hooks allow to simplify the core of it to just render that just runs every time it's necessary into which you are bringing in additional functionalities as needed.
I don't think new paradigms are a bad thing, I think the problem with hooks is that they are a "clever trick" to work around the fact that the language/runtime does not have the necessary features to support the developer experience that they would ideally have.
What's sad is that the class-based component system did have those necessary features, it also had a nice distinction between components and their lifecycle and the rest of your code. Now with hooks, everything is React lifecycle code, unless you're really smart about your API boundaries, and in my experience no one makes good re-usable hooks that are nicely isolated from business logic.
> they are a "clever trick" to work around the fact that the language/runtime does not have the necessary features to support the developer experience that they would ideally have
I'd call that a pretty good definition of a "design pattern."
Hooks are a new paradigm? That’s news to me, hooking is at least as old as two decades when I first started programming. Hooks are, like most programming ideas, hard to understand at first but easier as time passes and you see more of them.
One of the best things ever invented in component based frontend frameworks. It makes purely functional frameworks like modern react much easier to deal with.
Off course it's a violation of some theoretical principals. So what?
What I don't get: people complain about not being able to handle all the useEffects, but they probably shouldn't be there in the first place. In my experience most ambiguous use effects can be easily removed. They are rarely needed for anything but library code or interaction with browser APIs.
> people complain about not being able to handle all the useEffects, but they probably shouldn't be there in the first place
I think this is the crux of the issue. One's view of hooks depends a lot on the sorts of codebases they've worked in. Maybe the sun has always shone on you, and you've only ever worked in projects where hooks have been used sparingly and with great consideration.
You're very fortunate if so. I've seen some truly horrific hooks-enabled messes that have had to be outright abandoned because they became too complicated for anyone to understand or debug.
My junior developers started to come to me with the question: how can I do this without useEffect? Because they already know that their PR will be rejected. Usually we can figure it out within a few minutes, and make everything less complicated.
People are just way too much thinking imperatively, like decades of OOP thought them (and many of their educators). Most naive useEffects are just masked derived state.
> It makes purely functional frameworks like modern react much easier to deal with.
But hooks aren't pure functions. They aren't referentially transparent and have an implicit dependency on call order. Likewise, React components aren't "functional" the second you use any of these APIs which subscribe to effects, state, context, whatever coming from elsewhere. React is simply not a "pure functional" enterprise and it's strange to represent it as simply a "violation of some theoretical principles." Those principles are the entire basis of what constitutes functional programming, which is why the original parent described this as not-functional not-oo.
Maybe, it's just me - I miss the good old days when sites didn't have anything to do with react or similar. Everything was just plain old hyperlinks and some basic JS. I am not even talking about the 90s, just look at what Facebook used to be in its early days - such a simple UI, just based off of hyperlinks, very basic JS. That simplicity alone made it such a joy to use.
Today, I don't even feel like logging into Facebook, because a fucking dropdown menu for a post (which barely has 4-5 options) is a Component that is loaded via AJAX. This is not even an overstatement.
I don't think it's just you. Plain hyperlinks coupled with modern connections and equipment feels fast and easy. You click and a page appears. With JS apps they just feel heavy and almost buggy even when it is just a page of text with links.
Maybe I'm just in adt and marketing ech too much but it's almost like I can't be too fast on clicking thing otherwise things get fucked up and lose their states.
I was always surprised that a bunch of people looked at Facebook's website and said, yeah, I want their code to be the next big JS framework. Facebook has behaved for me for the past year or so, but for years prior to that, visiting their site was just an exercise in frustration for me. It was mainly because of components that remained in the gray loading state but never loaded. The messaging window used to do that for me about 50% of the time. Whenever I visited Facebook, I used to instinctively put my fingers over Ctrl-R in case I had to reload.
Also, one time, they managed to deploy code that broke form submissions under Firefox but not Chrome. I would be more understanding if it dealt with some cutting-edge features of HTML, but these are HTML forms. Mosaic had support for them in 1993.
Good point on the two Reacts. Call me old-fashioned, but I still prefer being able to serve a React app over a CDN instead of needing a Node.js server. Might be in the minority these days though.
The React ecosystem has been trying very hard for a long time to enable developers to write code that is objectively bad, vis-a-vis colocation of concerns all in a single bigass, hard-to-understand function. Hooks were last straw for me, but the trend began before that.
React components should be simple stream transformers, nothing more. Accept props as input, produce deterministic HTML as output. All that other crap? Calling the API, massaging the data, business logic? That belongs somewhere else, outside of your component.
Nobody's forcing them, no. But often there isn't anyone preventing them, either. React happily hands these developers enough rope to hang themselves.
To be clear: I don't mind React per se. Some of the best UI codebases I've worked in were React -- they just had a very strict separation of concerns and one-directional data flow via something like MobX or Redux. All the business logic was kept separate from the UI. But that's not fashionable these days.
I have to say that I've seen Redux being abused until insanity (and probably misunderstood) much more often than hooks. And much harder to clean up that mess, because it's a centralized mess. The hook mess is usually decentralized and can be improved incrementally.
What kind of frontend stack would you recommend that enforces keeping some meaningful separation of concern, without limiting productivity?
I will concede your point about horrible Redux codebases. I think I've tried to push that dark era out of my mind.
Without limiting productivity, I have no idea. I think you have to limit productivity along some axis or other, otherwise your codebase just turns to quicksand.
I sorta feel the same way. I used to be excited to spin up a react project, and loved working with it daily for 8+ years. It really was wonderful. Junior devs used to be able to write clear, performant, bug free code in react without a ton of hand holding. One of its greatest testaments. Now you need to spend 20 minutes figuring out what someone is trying to accomplish with a useEffect hook with 10 dependencies and if it’s running as expected or if that dependency should be wrapped in a useCallback. :) And that’s without even getting into the deep end of server components and bifurcating your frontend into static server and client components and hydrating the dom and using next router and blah blah blah. And we are told to use a framework by a VC backed company because create react app isn’t maintained anymore? Ok. Gonna go write some erb in rails or something.
I think is because boot camps pushed out bad developers. You can write bad code in any language framework, react isn't any different. We now just have a ton of front end devs that don't understand how to write good software
Share the same sentiment. React has gotten weird. It feels like they took a perfectly done design and awkwardly pushed it over its boundaries. (They got away with hooks, but this time it’s different)
Funny thing is they say it’s for the DX to become more like PHP. But the PHP I remember was practical.
Server components, which are in Next.js (using React's canary branch). Server components are not yet in official (i.e. non-canary) React, and the React team supports this move (as do I). I just wish that the tool that was so helpful with the "other" (100% client-side) React, "Create React App", was better supported these days.
Create React App is in a strange, pseudo-death state.
- It is not listed as an option for starting a new project in the React docs[0].
- The last release was April 12, 2022.
- The last time I created a new project with CRA, it printed a console log that claimed CRA was deprecated. However, the message seemed to originate from a dependency rather than CRA itself.
All this was enough to convince me to move to Next.js for future projects; though I find Next.js overcomplicated and full of things I will never use.
Nextjs is pushing for the server components and I don't really blame them for doing so. Netlify is trying to back anything that's not nextjs. If anything I'm kind of surprised that big cloud players are completely ignoring this market right now.
The more I get into RSC I have the feeling their main purpose is to pump up Vercel bills. A reason to buy more of their expensive compute resources.
They are nice in theory, but I don't see that many benefits over simple SSR, or the more traditional concept of server generated HTML with interactive islands.
Next.js applications often feel way less responsive than SPAs with proper pre-rendering on first load.
The speed problem imo is completely fabricated and is an angle to sell you their cloud offering. The mobile web is already unusable thanks to cookie banners, various popups, and ads. Loading spinners are the equivalent of Don Quixote's windmills.
I think it would be great to improve the speed of web applications. Including all the advertisements ;)
But I'm really doubting if Next.js is actually solving this problem. They are heavily caching everyting, so it might bring big benefits with slow and weird backend systems.
Comments here show me that useEffect() is apparently incredibly hammer-shaped. And all things related to state and network look like nails in the eyes of frustrated React users.
I think those people would be better served by frameworks that hold fine grained reactivity as a virtue. If you have appetite for spaghetti at least use real pasta instead of trying to roll steak into thin stripes to tangle it.
Many people tend to gain a good understanding of React by building on top of it. Unfortunately, majority of the tutorials, lessons, recommendations, and paid courses usually start off using a framework where a lot of stuff have already been added. The effort to simply understand a complex setup as compared to starting React with the bare minimum and slowly adding whatever packages / libraries are needed.
React should start by a simple initialization:
-> Setup React
-> CSS library
-> State management
And then, other packages or libraries can be considered to be added whenever the current needs of the application exceeds what the bare minimum setup has provided.
While in the end the set of packages and configurations performed may tantamount to what a framework already provides easily, the cognitive load starts on a piece that is well understood and grows alongside the evolution of the software product being delivered.
A couple of things make React extremely valuable to me:
- The functional programming model (State => UI) allows building very complicated interfaces in a very simple way, by defining dependencies with useEffect() and other hooks. It can take years to master it, but when you develop complex apps where all kinds of state needs to update when some other state changes, you really appreciate how simple it is to do with React.
- React is very backward compatible and allows you to migrate codebases to newer React features slowly over the years, while already using those new features in other parts of the code. (I still have some class-based components here and there.)
- There is a huge ecosystem of existing React components and tools you can use in your applications. They make it a very productive environment to get stuff done quickly. Frameworks like Next.js make it a breeze to develop and deploy static apps e.g. to S3.
- You can apply your existing React skills to React Native when you need native apps.
Please don't. useEffect() is for pluging 3rd party DOM components into react. Not for doing anything else. Definitely not for any state manipulation or dependencies.
What you should have gotten from this list of every possible use (and misuse) of useEffect is that it's for interaction with external things. And if you are doing a lot of interafacing with external stuff you should use a dedicated service for it, not pollute your code with ad-hoc bits of interaction, each wrapped in their own bespoke useEffect().
And the linked section talks about specifying dependencies of the code block inside useEffect()
You don't define dependencies WITH useEffect. You define dependencies OF useEffect. And you don't have much choice in the matter. Any local variable (also parameter) of render function needs to be a dependency of useEffect code. As this section states.
You can overuse useEffect() for sure. But I don't know how else you'd react e.g. to the page query string parameters or component properties changing, when the rendered content depends on them.
The whole point is not to use it directly in your components. It is implementation detail of that particular router. You might use router that interfaces with Redux not React directly.
Or you could write your router in the form of a service that lives directly in the history api event handlers and communicates directly though react state setters of some top-level component. Not a single useEffect needed.
Besides, router doesn't usually send you anything. It just sets props on your components according to url.
Okay, but my point is that somewhere along the line there always is a useEffect() that reacts to something. Maybe it's in your own component, maybe it's in a third party component.
I don't agree with your point. You can use state setter from outside of react and inside react rely only on state and props and not use useEffect() at all.
You don't need useEffect() to react to anything. React itself reacts to state and props change.
You'll do yourself a favor if you ban yourself from using state setters inside useEffect(). Try it.
I think that would only make my apps much more complicated, and also more difficult to understand and to develop, since they would not rely on standard React API but some kind of outside integration. I don't really see the value.
One benefit is performance. useEffect() causes cascading updates when it alters state.
The other is that it's way harder for your code to turn into spaghetti if you don't sidestep the whole concept of React where raw events trigger global state updates which causes react to do automatic re-render of UI which provides user with means of generating events. React should have one large loop, not multitude of small ad-hoc ones built on the side with useEffect().
You do you. But notice how many people here complain about performance and piling up mess in their React projects. Avoiding useEffect is a way to avoid those issues.
Everyone fucking off & writing frameworks that oh just so happen to be server side is incredibly bold self dealing. Now front and back end are deeply conflated, and instead of finding consistent controlled paradigms to tackle async on the front end we've just made an even bigger soup of what-renders-where-when.
We have been deeply mislead these past couple years. React ecosystem should have been working on better faster front end systems that integrate data better. Redux should just have been a start. Instead, managing data has gotten more complex and worse.
Has anything really changed since around 2021? That's when I started using it. And I never looked back, except for very simple projects where I use vanilla HTML/CSS/JS.
It is ridiculous to suggest that React is worse today than ten years ago. Remember all that time people spent battling their build scripts? Or what about the obtuse 3rd-party state management libraries everyone used to augment class components? It was torturous from the start.
We use Preact nowadays. It feels so much better and intuitive having first class support for ESM and use the browser's technologies for events, for instance. The TSX to JS transpilation is a bonus.
In general, for us: the Vite + Preact team feels just right.
React is overengineered. I guess it may have been worth it at some point in the past but the reality of browser tech has changed significantly and now there exist simpler ways to get superior results.
There's nothing wrong with html/css/js. They are a joy to use really. We're just discussing the abstraction of React here. No need to completely disregard them. You can't eitherway.
No new releases since June 2022 is a good thing. At some point you declare React complete and you put it in maintenance/optimization mode. No new api surface. Full backwards compatibility.
React is darn good. Don’t mess with it and go into enshittificaion.
I've worked on 4 large react code bases and they always devolve into these blobs of non-deterministic async state with unpredictable performance.
I actually like JSX and the component model so I just use solid-js which is everything I like about react but with effortless performance and you can actually get away with never using effects so your code can actually be deterministic.