When your just using vanilla react, I've never had a problem with hooks being that hard to reason about. Once you add in SSR, routers, query caching frameworks, etc the "lifecycle & state" starts to get confusing.
This is mostly a problem with the additional complexity of these frameworks (nextjs, tanstack) and not react at its core. Building an app with just react (and maybe redux) feels so simple and natural once you learn the paradigm.
I guess redux solves both "state" and "messages" at once, that's good. But what you work with then is not "vanilla react" at all. I don't even think "vanilla react" can really exist, beyond toy examples. You either use frameworks or write them yourself (worse).
You can develop extremely powerful web-apps using just React + Redux. Once you need to start dealing with SSR for SEO & server side caching, data preloading, hydration, etc... things get complex.
But honestly that's because those concepts are inherently complex and that complexity can only be reduced so far. Another problem is they get baked into these framework as the "default" and often over utilized when they aren't actually needed.
Yes, class components.
Function components help in reducing boilerplate code when all you want to do is put together a component that is a thin wrapper over other components with barely any state or logic.
The problem with function component fundamentalism rears its head when you start to add state and life cycle handlers, as you start to pile hooks on top of hooks when simple inversion of control would make things cleaner and easier to manage.
Literally the main criticism thrown at class components is boilerplate code and support for life cycle methods. It turns out that they are a nuisance when writing small stateless components, but are an unavoidable need when you add non-trivial state and life cycle handlers.
I agree with JSX, and function components are nice, but React is most definitely not just function composition. Hooks add state and introduce life cycle events that take components way beyond stateless territory, to the point that it would be far easier to reason about them if they were class components with properties and decorators and handlers invocable through inversion of control.