Comment by rimunroe
> Hooks addressed class component pain but introduced new kinds of complexity: dependency arrays, stale closures, and misused effects. Even React’s own docs emphasize restraint: “You Might Not Need an Effect”. Server Components improve time-to-first-byte, but add architectural complexity and new failure modes.
There are a lot of valid criticisms of React, but I don't think this is one of them. These problems are not really new with hooks. They're actually problems which existed in some form in the class component API. Taking them one at a time:
Dependency arrays: I cannot count the number of bugs I encountered which were due to a lifecycle containing some code which was supposed to be called when certain props or bits of state changed, but completely forgot to check one of them.
Stale closures: the second argument to setState allowed this exact bug. Also, people would bind methods in incorrect spots (such as in lifecycle methods) which has the same result.
Misused effects: at varying point, class components had access to the class constructor and the lifecycle methods componentWillMount, componentDidMount, componentWillReceiveProps, shouldComponentUpdate, componentWillUpdate, componentDidUpdate, componentWillUnmount (this is from memory and is definitely only partially complete). Misuse of these was incredibly common. An article like "You Might Not Need an Effect" but titled "You Might Not Need Lifecycle Methods" or "You Might Not Need the Second Parameter to setState" would have been very helpful in the past.
Hooks reduced the number of opportunities for making mistakes, make enumerating those opportunities easier, and, critically, made them easier to detect and warn users about.
The dependency array thing is really easy if you use eslint with the react rules of hooks.