> If there is anyone here who has time to explain to me (or link articles about) why functional components and hooks are considered to be better than class components, please enlighten me.
Static evaluation of which instance properties are being used in a class instance is much harder than evaluating which variables are being referenced in a function. There's no need to worry about calling context or binding instance methods. Functions minify much better because you don't have to worry about preserving long property names like componentDidUpdate. With class components, sharing logic involving state between components required either functions taking a state setter and whatever slice of state you needed, or--more commonly--higher order components. With function components and hooks, the code responsible for initializing and updating state isn't tied to an instance. Now you can share that code with a plain function without needing to pass an entire slice of state and an update function into it. Instead of needing to shove all your update-related code into the same componentDidUpdate or componentWillUnmount methods, you now split them into different calls to useEffect.
> Suddenly everything is intermingled in one function and we're using side effects to react to changes and manipulate state. I could no longer understand when which code was executed, and especially following and manipulating state became impossible for me.
If you're talking about using useEffect to respond to changes by setting state: that's almost always a code smell and sounds like trying to sync state with props. This was an anti-pattern long before hooks, and was called out explicitly in the docs.
Having worked on a lot of class components and function components, class components offer a lot more opportunities for bugs which can't be statically prevented. On the other hand, most of these bugs can be caught in function components and hooks by a linter, or are just prevented entirely by the design. A frequent question which came up during the class component era was what code belonged in the class's constructor, componentWillMount, or componentDidMount methods. This always came with caveats, because generally component initialization isn't something developers should be thinking about because it can happen many times before anything appears on screen. Function components offer fewer opportunities for this. The useEffect hook forces people to think purely in terms of running effects in response to changes in variables which have been closed over, and about what things need to be done to clean up after the effect has run. Responding to user events (e.g. onClick) is almost exactly the same as it's always been other than cosmetic changes.
I'm not sure how everything being in a single function offers worse organization than everything being within a class. Instead of instance properties you have variables. Instead of methods you have inner functions.