Class component hook integration rather than functional component
See original GitHub issueDo you want to request a feature or report a bug? Feature
What is the current behavior?
Currently the Hooks API is compatible with functional components only and Hooks are simply functions.
It seems to me that Hooks are a declarative concept that are being implemented in an imperative manner and it’s causing the need for useRef to imitate instance variables and brings about the need for rules (should be called at the top level, in the same order). Hooks are executed on every render which wastes cycles.
I think if Hooks were implemented as classes and were compatible with class components rather than functional components, the interface would be a lot more intuitive and it would knock out a lot of the quirks we’re seeing with Hooks in 16.7.0-alpha.2.
Mixins were implemented in a similar way and two of the major concerns were implicit dependencies and namespacing conflicts, but in the code I’m about to show, both of these are non-issues as all hook logic is self-contained.
I think an interface like the following would have a lot of benefits with only a couple drawbacks
class WindowResizeHook extends Hook {
hooks = {
dimensions: new StateHook({
width: window.innerWidth,
height: window.innerHeight
}),
windowSizeSubscription: new EffectHook(() => {
const handler = () => {
this.dimensions.setState({
width: window.innerWidth,
height: window.innerHeight
});
};
window.addEventListener("resize", handler);
return () => window.removeEventListener("resize", handler);
}, [])
};
getHeight = () => this.hooks.dimensions.state.height
getWidth = () => this.hooks.dimensions.state.width
}
class Foo extends Component {
hooks = {
counter: new StateHook(0),
windowResize: new WindowResizeHook()
};
incrementCounter = () => {
this.hooks.counter.setState(prevValue => prevValue + 1);
};
render() {
return (
<div>
<div>{`Width: ${windowResize.getWidth()}, Height: ${windowResize.getHeight()}`}
<div>{this.hooks.counter.state}</div>
<button onClick={this.incrementCounter}>Increment Counter One</button>
</div>
);
}
}
Pros:
- wouldn’t have to worry about using hooks at top level of function
- would be instantiated once as opposed to on every render
- wouldn’t need useRef to imitate instance variables
Cons:
- couldn’t destructure hooks like we do today
My knowledge of react internals is little to none, so perhaps this implementation is infeasible for reasons beyond me, but I think Hooks are better represented as classes than functions. I think class representations would reduce a lot of the “magic” people are talking about. Also, surely missing some pros and cons so feel free to add some.
Even if hooks remain available only in functional components, it would be nice to see some of the implicit magic pulled out into an explicit interface. I would gladly write a little more boilerplate if it meant having a more explicit interface.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:9
- Comments:7 (3 by maintainers)
Again classes are harder to process with compiler. This is one of the point of hooks.
Closing this as it’s clearly a bust. Hooks are powerful no doubt, but the interface is awkward at best.