The examples in https://usehooks.com/ aren't convincing me for some reason, but maybe that's just my lack of familiarity with the syntax so it feels more magic. Lifecycle methods like componentDidUpdate are super easy to reason about at first.
The examples in https://usehooks.com/ aren't convincing me for some reason, but maybe that's just my lack of familiarity with the syntax so it feels more magic. Lifecycle methods like componentDidUpdate are super easy to reason about at first.
You can separate different reusable pieces of logic into Hooks, and then combine them or pass values between them. You can even call the same Hook more than once.
I’ve wrote about new possibilities they unlock here:
https://medium.com/@dan_abramov/making-sense-of-react-hooks-...
Hope this helps.
class Foo extends React.Component {
constructor(props) {
super(props)
this.useEffect(…);
this.useState(…);
// or maybe even a top-level API:
useState(this, …);
}
}Note Hooks execute on every render. That’s their whole point.
I explain this here: https://overreacted.io/why-do-hooks-rely-on-call-order/#flaw...
I've used the hooks myself and I like the composability, but I can also understand the vitriol from the community. And so far my biggest complaint is that I can't use them in classes as well. I think if you treat them as a more core/composable type of object then you can use them in the same paradigm as Component classes.
My example here changes the names of the typical lifecycle events for clarity but you could use the component lifecycle names instead. Point is it should match the component lifecycle and allow the user to hook into each one separately but wrap everything up into a meaningful collection. A hook must be declaratively defined as a property in another class (I use the @annotation syntax here but I realize it's not standard yet), and that allows react to keep a consistent ordering on how/when hooks are called during lifecycle events. It also allows the hook to register itself for the lifecycle of the owner.
<code> class UseWindowWidth extends Hook {
// normal style of using state
state = {
width: this.props.value
}
// or maybe use state hook for new style
//@hook(UseState, this.props.value)
//width;
handleResize = (evt) => {
this.width.set(window.innerWidth);
}
hookDidMount() {
window.addEventListener('resize', this.handleResize);
}
hookWillUnmount() {
window.removeEventListener('resize', this.handleResize)
}
getWidth() {
return this.state.width;
}
// other public methods here would allow owner to do things
// ? although this doesn't fit well with top-down props style
}class MyComponent extends Component {
// @hook registers the hook into lifecycle events and
// passes props to UseWindowWidth hook. Also, any changes
// to hook state should cause a forceUpdate of the component
@hook(UseWindowWidth, { value: window.innerWidth })
windowWidth;
render() {
let width = this.windowWidth.getWidth();
return (
<p>Window width is {width}</p>
);
}
}
</code>The 'props' concept might not make sense with the Hook object as I have it here, cause I can't see a nice way to declaratively update the props instead of just calling setters, but that might be ok for how these would be used.
I'm not in love with this yet, and there's some other things that would have to be ironed out (like coordination between hooks), but I think it opens some ways to allow hook use in class components as well.
Grouping these parts this way means they can be trivially extracted as a Custom Hook[1] (analogous to a 'mixin' or 'trait' in OOP).
By extracting this concern into a Custom Hook it can easily be reused by different components, as well as composed by other Custom Hooks. This was previously possible using Higher Order Components, Render Props and the (really old) React Mixins concept, but Hooks addresses problems with each of these previous approaches.
If you want to know more about how Hooks improves over these previous approaches, see my previous comment: https://news.ycombinator.com/item?id=19074469
Their bad part is, they add another concept besides components.
Their good part is, they allow to convert non-display components to hooks, which removes the guessing of where the logic is stored.
But the benefit is tighter encapsulation of functionalities. No longer do we have to spread a feature's logic across multiple lifecycle methods that may share that space with logic from other features.