However, there is a major value hooks provide over class components and that's the composability of the lifecycle effects. The problem with class components is that code for a lifecycle is broken across multiple functions and interweaved with other effects. This happens because the declarative model of the component tree clashes with the imperative ordering we code up for lifecycle functions attached 'within' each class component. The fix is to turn lifecycle effects into first level declarative concepts themselves (like in hooks) so they're not 'within' the component, instead they're more of a has-a relationship.
This would actually be rather simple to do, drop the lifecycle methods in a component, and add a new Component.addEffect function (or, cause I'm a big fan of decorators, you could have some decorator to declare what effects should be used). And each effect would be another class that inherits from Effect. I think the hardest part to think about is how you interweave the effects like people do in hooks as one output becomes the input for another, but I think this is probably the wrong way to think about it. Instead if you think of it as an Effect tree then each Effect is just a 'render' function where you're passing in other effects as the props and the output is passed down the tree, so you'd just need an inline effect function that would compose 2 effects together the same way we do with components. At this point the conceptual model is extremely easy cause it's declarative trees all the way down!
RootComponent
|- ComponentA
|- effects
||- lambda effect -- myClickEffect
|| |- myStateEffect
||- lambda effect -- myKeyEffect
|| |- myStateEffect
||- myCleanupEffect
|- children
|- ComponentB
|- effects
|- children
|- ComponentC
|- effects
|- children
...
Anyone wanna pass this idea onto the react team that'd be awesome cause I'd love to see this added for Class components to make them more composable as well as having better sharing of ideas between hooks and class components :)