You can't compose behaviors effectively with class based components, and the fact that you only have one of each lifecycle method means that they become an absolute mess as you scale with complexity. Each behavior gets split up across multiple lifecycle methods, mixed in with every other behavior. With hooks, you can encapsulate each behavior into a single hook function that handles its complete lifecycle, and then trivially use it anywhere else.