3 ms·
Hooks address a very specific problem with classes: composability. You can use the various builtin hooks to do stuff that (in class-based React) previously req
by mambodog 8y ago
Hooks address a very specific problem with classes: composability.
You can use the various builtin hooks to do stuff that (in class-based React) previously required implementing methods (eg. componentDidUpdate). Using those methods works fine until you want to split out and reuse part of those methods in other components.
You can certainly try class composition: creating little classes that you call in each of the relevant lifecycle methods. However this adds a lot of boilerplate to components which use the composed objects (as is common with class composition). It's also awkward to share the setState API with these composed classes.
The Custom Hooks approach[1] with React Hooks just makes it really easy to use state and lifecycle functionality when extracting common behaviour to can be shared between multiple components.
React has tried to address this composition issue several times in the past, and I think hooks are the nicest yet:
React's old 'Mixins' feature got a lot of the way there, but still didn't compose perfectly. For example, you had to avoid method and state key name collisions between mixins.
Creating a 'Higher Order Component' is another approach, which is less verbose than class composition, but makes your component tree deeper, and can also be annoying to statically type.
The community also came up with 'Render Props' to address much the same issue.
And of course, you can always just continue to use classes if you aren't experiencing any of these pain points.
Hooks just compose quite nicely in cases where none of these other approaches do.
[1]: https://reactjs.org/docs/hooks-custom.html https://reactjs.org/docs/hooks-custom.html
- goatlover 8y agoIs all this because inheritance is discouraged? Seems weird to got to that much trouble to avoid a builtin language feature that does the thing you want, which is reuse methods across components.
- mambodog 8y agoHow do you compose two base classes into a subclass? That's basically what hooks allows. You can use two different, unrelated custom hooks in one component, and a different combination in another component, without having to bundle them into base classes.
- sowhatquestion 8y ago> How do you compose two base classes into a subclass? In most other OOP languages besides JS, the obvious answer would be to use traits.
- mst 8y agoHence why I've been playing around with class decorators and friends to try and figure out a nice way to do method modifiers, traits, etc. But I got sidetracked with "but howtf do I make typescript understand the resulting signatures" and then got nerd sniped by something else. Hopefully eventually I'll get back to it.
- danabramov 8y agoIf you want to understand what Hooks are for, I wrote this piece: https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889 https://medium.com/@dan_abramov/making-sense-of-react-hooks-... I hope you find it helpful! Hooks aren't _quite_ like traits or mixins or anything else. You can apply the same Hook multiple times and pass values between them. That's what makes them powerful. Look at my last demo. https://overreacted.io/making-setinterval-declarative-with-react-hooks/#bonus-fun-demo https://overreacted.io/making-setinterval-declarative-with-r...
- mst 8y agoYeah, definitely a different beast. I've done things with what's basically dynamic scope trickery before now, though it didn't look exactly like hooks. I still want traits because I've got very fond of doing class-with-read-only-members type stuff and being able to compose functionality together works really nicely in that regard (nonetheless, I very much appreciate your efforts on elucidating hooks - I think most of the reason I'm replying this confidently is as combination of your articles and the reference docs :)
- mambodog 8y agoTraits are okay: React 'Mixins' which I mentioned in my parent post are basically traits but at the framework level, which allows them to be smart about composing/merging the use of framework functionality normally accessed by overriding superclass methods (eg. componentDidUpdate). Traits still have the composability issues I mentioned for React Mixins: how do you avoid collisions between the namespaces of different traits while still allowing some to compose others?