Taking the somewhat-arbitrary but reasonable standpoint that "stable" means that there aren't any major architectural changes required to bring a codebase up to modern standards, I think the best you can say is that React has been stable since hooks were introduced in Feb 2019. So about a year and a half of stability, which isn't horrible but it's a far cry from stable since 2015.
At $DAYJOB we have no intention to rewrite our older class based code to hooks (except where we're otherwise making significant changes to that bit of code), and indeed we're still writing some new code in the class style.
If you feel like you need to upgrade then I think that on you, not the framework.
Another reason is the ease and speed of online documentation/resources. We all use StackOverflow to get answers and insight into problems we face on a daily basis, and as the framework (or library) progresses, the majority of Q&As adopt it, giving us a wealth of resources at our disposal.
While React apps in 2015 probably still work with the newest versions of React, you can't put a 2015 React dev in a 2020 project and vice-versa as if nothing's changed.
Our app is still using Redux, so I guess that one hasn't hit us yet (but there's also no real reason for us to update to a newer method).
https://blog.isquaredsoftware.com/2018/03/redux-not-dead-yet...
https://blog.isquaredsoftware.com/2020/10/presentation-state...
Sure, it's definitely _peaked_, because there's a lot of other great options in the React ecosystem these days. But, there's still plenty of good reasons to use Redux. And, with our new Redux Toolkit package and the React-Redux hooks API, "modern Redux" code is a lot different than what you've seen in the past, as shown in our new "Redux Essentials" tutorial:
https://redux.js.org/tutorials/essentials/part-1-overview-co...
This is often the case in practice. But it's a pretty easy problem to avoid. Usually those packages simply aren't necessary in the first place.
React project in the wild seems to exist in two modes from what I can see, the constantly tended garden, or the write and move on and leave it to someone else to rewrite in future (otherwise known as write only, or abbreviated to perl). /s
IMO that's just poor engineering and not an inherent problem with React. The app I inherited at my current job had many such packages. And we have indeed had to update/replace some of them. However most of them were implementing functionality which could be trivially replicated in "plain react" so we've mostly replaced them with simple internal components and are not anticipating having the same problem in future.
Regardless, the diaspora of packages is just common culture in Javascript in the wild. As a reference, I site leftpad. As a remedy I offer the saying 'its better to laugh than to cry'.. :)
All of the code written with React 15 is compatible with React 16. And React 17. And React 18. And so on probably.
Admittedly those are trivial renames, but they've been renamed as such because they're very likely to be buggy with async rendering.