Sooooooooo many debates about React hooks.
It sometimes seems like people are either in love with the feature, or they completely hate it.
Myself - a hooks fan, but I'm aware of the drawbacks. I believe that everything in software is a tradeoff and has its drawbacks.
On many occasions though, I find arguments against hooks that are just an afterthought and don't represent the true considerations. In my opinion at least, which I'm sharing in this post:
Myth #1 - hooks have these annoying rules - and that means that there's something flawed about them.
Well, yeah - hooks have rules. But so do React classes.
Imagine I told you that all of your state must reside on the same object, must be initialized in a single function which must be named 'constructor', and you can only define one such method. Same of side-effects, each with its own specific name. Sounds pretty restrictive, no?
So it's not that hooks have rules and classes don't have, they just have different rules.
In fact, these limitations of classes are not only a mental overhead, they are a true obstacle for code reuse. If you want to write reusable code that connects to a socket, updates some state, and disconnect on component unmount - it's very hard to accomplish with classes.
Myth #2 - You keep encountering stale state and it's really annoying. If you need an ESLint plugin to write your code safely - there's something wrong with the feature.
Well, if you think about it, the ESLint plugin is not a burden of hooks, it's a benefit. With classes, if you didn't re-run your effect after the dependencies changed - nothing will protect you against it. For example, if you set up a setInterval on componentDidMount but forgot to update it on componentDidUpdate, or forgot to reset it on componentWillUnmount - there is no tool that will alert you that you're doing something wrong. The
exhaustive-deps ESLint rule is like TypeScript for your side-effects, it prevents you from writing bugs in compile time.
The same can be said about memoized values. If you memoize a function, but forget to invalidate the cache on certain values - here comes the ESLint rule to protect you against it. In fact, if you don't write any bugs, you won't even know the ESLint rule is there.
Myth #3 - Hooks trade a more explicit API with a more implicit one, at the cost of moving the state and order of execution to behind the scenes
Well, in fact that is not true. The state and order of execution are behind the scenes anyway and completely managed by React. True for hooks, and true for classes. The "this" in classes is just an illusion that makes developers feel more in control, where in fact - React is the one managing the state behind the scenes, and making sure "this.state" is updated by the time our code runs.
Well, have you ever tried to define a constructor in a loop? What about returning a Promise that resolves to JSX instead of returning the JSX itself - have you tried that as well?
A framework works in a certain way and expects specific values and formats from the developer. If you don't follow the rules - things break. A sign of a good framework though, is if the rules are simple to remember and reason about and provide tooling to help prevent problems. The rules-of-hooks ESLint plugin is like an extension of TypeScript to help the developer keep the format.
That being said, I completely understand the arguments about hooks, and I'm not religious about any technology. It takes time to get used to a new syntax, and to truly understand the benefits to it.
It's sometimes tempting to think that the people that created the API made a terrible job, and that there's probably a much better solution. But, there are many considerations that the React team has that you might have overlooked. I strongly recommend going over the discussions on Github for the Hooks RFC, and Dan Abramov's blog overreacted.io, in which he explains the motivation behine some of the decisions.
And if you still disagree - that's cool :)