I understand and agree with many of your thoughts. I use Backbone as a point of reference, not to compare the two (that’s apples to oranges) but to affirm Backbone was easier to debug.
Even async code with Backbone was easier given the shallow number of frames in the backtraces. And the ability of Chrome Dev Tools to blackbox vendor libs (not done with React) enabled stepping through non-essential libs. It was possible to step from one piece of app code, past a library’s internals, directly into more app code — avoiding almost all lib distraction and affording actual step debugging without having to bail just to do guess and check somewhere in the app source (a very time and cost intensive operation).
When you say almost always, well, that concerns me. Because almost for you could be a real head scratcher for others. Especially if they don’t know what proper step debugging should feel like.
And, even for the seasoned dev, the incremental cost of having to dig even two frames deep into vendor code, or break a debugging workflow because lib stuff is impeding them, multiplied by hundreds of thousands of developers, thousands of times over, is not only bad DX, its poor design.
Had Backbone been invented today, the functional paradigm would have been a no-brainer during creation, and atomic state would have eventually come to pass.
Nevertheless, React has gotten us far. But at what cost? And with how many man-centuries wasted with a poor debugging workflow? Only time will tell.