It's actually kind of clear why they behave like they do (they're called in sequence), but the consequences in terms of code organization and structure are... meaningful, at least, if not outright jarring.
You can't have a hook called inside an if branch, for start. That's enough to be a game changer. But then, the usual lifecycle hooks like componentDidMount and so on are all condensed inside useEffect with its special second argument logic.
With classes we had a clear idea of the lifecycle of a component. With hooks it's distributed inside a lot of use* functions with often not really meaningful names.
Not that the names chosen by the React team are clear either, mind you. useCallback, useReducer, useLayoutEffect and so on aren't IMO clear at all about their intent and usage. Compare those names with the aforementioned componentDidMount.
I've found myself read the documentation about them more times than I'd have liked to. And I think I'll do that again on the next project π
All in all, I think hooks are a clever and simple solution to most of the reactive application problems, but they're a shifting paradigm - not that it's unsurmountable but enough to make "classic" React something completely alien. At this point, would it be so bad to fork React into a hooks-only separate library?
If I have to consider something, give me a hint of what it's about π
Anyway, interesting video, very clear. Shawn is excellent at explaining stuff.
But, IMO, the point still remain. A developer could learn those things, but they shouldn't be forced to do so. They're glimpses of the internals of hooks. But, as Shawn says at the end of the video, that's not React - so it's unclear how, for example, removing a component from the tree affects the hooks array. Or why you can't use hooks inside class components. Or why there's a useEffect hook but also a useLayoutEffect and how - or why! - they differ.
This is complicated by the fact that function components do have a lifecycle just like class components, but it's hidden under the rug of hooks.
I also wonder why, at this point, it is the case. I.e., why a lifecycle seems so natural at this point. It's not like someone imposed this concept on everyone - maybe it's just because we usually see something "coming to life", "living" and "dying" that we apply this idea even to application components π¬
Also, React indeed has a "cycle" to make things work - the work loop. Which works well with JavaScript's event loop too.
In the end, I'm unsure if there are solid, evident advantages about hooks that makes us say that they're definitely the better way to create (React) components. They comes with compromises, like basically everything else, and I'm unconvinced that the drawbacks could be nullified by mere habit.
But for now, I still think it's too soon to declare something.
My feeling at the moment is that Hooks is an attempt to solve issues they created themselves by pushing functional programming too far (HOC wrapper hell, etc.).
That's weird because it's pretty easy and elegant to avoid those problems if you use the right OOP patterns (adapters, dependency injection...).
I wish they had improved the class usage rather than introducing those terrible, anti-pattern, useThings.
They are shiny and new, they are nice for small components and todo demo apps, but for large apps, the problems remain.
I agree with this, but I feel that its way too late now.
Interesting statement. Hooks became stable on Fabruary 6th with React 16.8, not even 6 months ago. When do you think it was the appropriate time? Maybe before so many libraries using hooks popped out like mushrooms after the rain? π
Also is the intention to eventually fade out "classic" react?
They (React maintainers) said there's no intention to dismiss class components in the foreseeable future. But what about the hidden intentions? In the end, the explicit goal was to push developers away from class components.
Was release only ~6 months ago? I started playing with hooks before full release though, so feels longer to me I guess...
I feel like the right time should have been when I was announced and was known to be so dramatically different. Have it as a React add-on. I imagine that there would be way less usage of it if that was the case though.
Idk really, maybe the ideal solution would be to go the babel route? @React/core with optional @React/classes and @React/hooks or something.
My name is Kent C. Dodds and I'm a Remix Co-Founder, JavaScript engineer, and teacher. I'm also active in the open source community. I like my family, JavaScript, and React.
I expect that classes will eventually be extracted to a separate package and a codemod will be made available to update code to use that package, similar to what was done with React.createClass. The react team is very interested in making it easier to build UIs with React and they feel that hooks is the way to do this. So putting hooks in a separate package wouldn't have pushed their goals forward very well. I'm happy with the way it's been done so far. It's a change, and that comes with a learning curve, but it's one that I'm glad to have for the benefits that hooks provide.
To add to this already great comment, hooks have felt more like a fad, not only in the way it was introduced but also the way it was adopted. For example, hooks was released partly to help with newer developers that don't understand classes. Some of my primary concerns are that the JavaScript community and ES standards have been heading in the direction of more OOP with ES6 -> ESNext. Hooks are a fork essentially moving away from that and more down the functional route. I agree there are times and places for hooks, but I feel they can be overused.
For instance, when you come across a functional component that has 6 different useEffect calls, the function ends up being 1k lines long, which isn't manageable. The same goes for finding a class componentWillReceiveProps that is super long too, the tool is only as good as the person using it.
My disappointment with hooks lead me to write a small HOC that allows writing stateful components without functions, and with all the functionalities of classes.
They work like black magic.
It's actually kind of clear why they behave like they do (they're called in sequence), but the consequences in terms of code organization and structure are... meaningful, at least, if not outright jarring.
You can't have a hook called inside an
if
branch, for start. That's enough to be a game changer. But then, the usual lifecycle hooks likecomponentDidMount
and so on are all condensed insideuseEffect
with its special second argument logic.With classes we had a clear idea of the lifecycle of a component. With hooks it's distributed inside a lot of
use*
functions with often not really meaningful names.Not that the names chosen by the React team are clear either, mind you.
useCallback
,useReducer
,useLayoutEffect
and so on aren't IMO clear at all about their intent and usage. Compare those names with the aforementionedcomponentDidMount
.I've found myself read the documentation about them more times than I'd have liked to. And I think I'll do that again on the next project π
All in all, I think hooks are a clever and simple solution to most of the reactive application problems, but they're a shifting paradigm - not that it's unsurmountable but enough to make "classic" React something completely alien. At this point, would it be so bad to fork React into a hooks-only separate library?
Consider watching youtube.com/watch?v=KJP1E-Y-xyo
If I have to consider something, give me a hint of what it's about π
Anyway, interesting video, very clear. Shawn is excellent at explaining stuff.
But, IMO, the point still remain. A developer could learn those things, but they shouldn't be forced to do so. They're glimpses of the internals of hooks. But, as Shawn says at the end of the video, that's not React - so it's unclear how, for example, removing a component from the tree affects the hooks array. Or why you can't use hooks inside class components. Or why there's a
useEffect
hook but also auseLayoutEffect
and how - or why! - they differ.This is complicated by the fact that function components do have a lifecycle just like class components, but it's hidden under the rug of hooks.
I personally think itβs only complicated because weβre so steeped in OOP and lifecycle methods this seems so alien.
Yes, that indeed might be the case.
I also wonder why, at this point, it is the case. I.e., why a lifecycle seems so natural at this point. It's not like someone imposed this concept on everyone - maybe it's just because we usually see something "coming to life", "living" and "dying" that we apply this idea even to application components π¬
Also, React indeed has a "cycle" to make things work - the work loop. Which works well with JavaScript's event loop too.
In the end, I'm unsure if there are solid, evident advantages about hooks that makes us say that they're definitely the better way to create (React) components. They comes with compromises, like basically everything else, and I'm unconvinced that the drawbacks could be nullified by mere habit.
But for now, I still think it's too soon to declare something.
My feeling at the moment is that Hooks is an attempt to solve issues they created themselves by pushing functional programming too far (HOC wrapper hell, etc.).
That's weird because it's pretty easy and elegant to avoid those problems if you use the right OOP patterns (adapters, dependency injection...).
I wish they had improved the class usage rather than introducing those terrible, anti-pattern, useThings.
They are shiny and new, they are nice for small components and todo demo apps, but for large apps, the problems remain.
That's an interesting take as they're using closures. Which as you may know isn't new, nor specifically "functional".
HOC wrapper hell is also interesting as in my experience most HOCs issues are down to bad architecture and exhibit similar as inheritance.
"They are shiny and new" - they're old. Only new in React land.
I agree with this, but I feel that its way too late now. Also is the intention to eventually fade out "classic" react?
Interesting statement. Hooks became stable on Fabruary 6th with React 16.8, not even 6 months ago. When do you think it was the appropriate time? Maybe before so many libraries using hooks popped out like mushrooms after the rain? π
They (React maintainers) said there's no intention to dismiss class components in the foreseeable future. But what about the hidden intentions? In the end, the explicit goal was to push developers away from class components.
Was release only ~6 months ago? I started playing with hooks before full release though, so feels longer to me I guess...
I feel like the right time should have been when I was announced and was known to be so dramatically different. Have it as a React add-on. I imagine that there would be way less usage of it if that was the case though.
Idk really, maybe the ideal solution would be to go the babel route?
@React/core
with optional@React/classes
and@React/hooks
or something.I expect that classes will eventually be extracted to a separate package and a codemod will be made available to update code to use that package, similar to what was done with
React.createClass
. The react team is very interested in making it easier to build UIs with React and they feel that hooks is the way to do this. So putting hooks in a separate package wouldn't have pushed their goals forward very well. I'm happy with the way it's been done so far. It's a change, and that comes with a learning curve, but it's one that I'm glad to have for the benefits that hooks provide.That's an interesting insight, Kent. Thank you!
To add to this already great comment, hooks have felt more like a fad, not only in the way it was introduced but also the way it was adopted. For example, hooks was released partly to help with newer developers that don't understand classes. Some of my primary concerns are that the JavaScript community and ES standards have been heading in the direction of more OOP with ES6 -> ESNext. Hooks are a fork essentially moving away from that and more down the functional route. I agree there are times and places for hooks, but I feel they can be overused.
For instance, when you come across a functional component that has 6 different useEffect calls, the function ends up being 1k lines long, which isn't manageable. The same goes for finding a class componentWillReceiveProps that is super long too, the tool is only as good as the person using it.
My disappointment with hooks lead me to write a small HOC that allows writing stateful components without functions, and with all the functionalities of classes.
github.com/Pensarfeo/react-makesta...
This is highly experimental, so I would appreciate some feedback on the project!
PS: No hooks were harm wile writing this package :)