This makes me very skeptical about the proposed feature in React, called "hooks", which is linked to in the article. It lets you add state to your functional components, and it looks like you end up bundling all your code into one function rather than having a separate constructor to initialise the state (to me, separating out that function is a good thing). I would be interested in the motivation for that.
Hooks will allow people to use "class like" features and behavior, but with none of the conventions forced by syntax, plus some pitfalls.
To me it seems a good way to ensure most devs (espacially unexperienced casual ones, which are legions in JS by nature of the market) will dump their logic wherever it works with as little structure as it allows. It's a technical debt catalyser, and will make sure nobody feels at home in someone else's code. The community will pay the price in a year.
It's also yet another way to do the same thing, and JS has already a lot of those. React as well. Documentations, tutorials and examples will suffer from it. But again, it's very common in JS land where learning anything requires gathering scattered puzzle pieces then assembling them, hoping they are from the same set this time. It allows me to bill more, so I'm not complaining, but it's not fair to newcommers.
Note that I can see some nice things about hooks. I just strongly think they don't outweight the cost by an order of magnitude.
FB idea of ergonomics and user friendliness, in API and UI, has always been to force their way into things, until it blocks, back down, and fix things when possible or use a workaround.
Having been training people in web tech for years, the consequences of such policy show in the classroom. But, hey, more money for me :) Plus when I dev, I have the experience to avoid the pain, mostly knowing when not to do or use things. But I can tell than many of my younger colleagues don't, and a few of my not so young ones too.
Still, I wish they gave a bit more though to this aspects of their products: their are brillant technicians, so it's not that they can't, it's just a matter of culture.
I've also had doubts about hooks since its proposal, and I agree with the points you raised.
From the Rules of Hooks section in the documentation[0].
- React relies on the order in which Hooks are called.
- Only call Hooks at the top level. Don’t call Hooks inside loops, conditions, or nested functions.
- Only call Hooks from React function components. Don’t call Hooks from regular JavaScript functions.
This design decision doesn't sit well with me, and I won't be using it. However, the community seems to have already welcomed it, so I'm forced to learn the intricacies to be able to understand React codebases and keep up with the latest trend..
The addition of this feature is sure to increase cognitive load and technical debt. There are already countless variations of state management libraries and patterns that encourage pure functional components and decoupled logic. Hooks seem to be yet another opinionated strategy - and not for the best, in my view.
> However, the community seems to have already welcomed it, so I'm forced to learn the intricacies to be able to understand React codebases and keep up with the latest trend..
That's one thing that no many realizes: the JS community is special and you should take that in consideration when adding a new features.
When I say special, I mean it reacts (puns intended) in a way no other programming community does:
- it jumps on novelty with very little afterthoughs or regards for consequences.
- it has an habit of disregarding lessons from the past.
- it seldom fix problems, but add a new layer of solution on top of it.
Knowing this, the way hooks are released is too me like giving matches to children with the only advice "look how cool it is, I can make fireworks".
Yes, I'm exagerating for the argument sake. But still, react is now a software used everywhere, I'd welcome a switch from "move fast and break things" to "let's think this true" once in a while.
This is a good way to summarize the javascript community. Not learning from the past is possibly a side effect of being dominated by young and/or inexperienced programmers and being less inclined to research established concepts before making something up. Although there are plenty of benefits to younger programmers (I hope, I'm one myself), but there are drawbacks to everything.
> will dump their logic wherever it works with as little structure as it allows. It's a technical debt catalyser, and will make sure nobody feels at home in someone else's code. The community will pay the price in a year.
I don't want to downplay your concerns, but I will say that this is already a problem. Part of the goal with hooks (and I can't say if it achieves that) is to encourage the separation of a lot of state-interaction OUT of the components. Today it is much too easy (arguably it is easiest) to write a component that is basically untestable - basically a mini-application in itself, which is the opposite of good React design.
I'm hopeful that Hooks will help, and I think the original demonstration focused too much on state and not enough on other interactions external to the component, which is where the real pain today exists. I've not played with the alpha at all to have a feel for how realistic my hopes are.
> is to encourage the separation of a lot of state-interaction OUT of the components
I get that, but I'm not sure it's in the interest of most projects either. The vast majority of React code base can (and IMO should) do the simplest things instead of going with a store. Redux and other means of putting state interactions out of components are a huge overhead in so many ways that I think it should be the exception, not the rule.
Besides, even for fluent react devs, it is a common strategy to create applications as a big fat component that does it all, then split it little by little into smaller parts as the need arises. Complexity management is hard after all.
It makes sense the FB team wants to promote a pure clean industrial flux pattern, so I understand why they go this way. I just note they are doing so, ignoring the fact the vast majority of devs work on code that never reaches anything close to their requirements. And if it ever does, it certainly doesn't start that way.
Same goes for tests. I'd say only one projects out of give I work on are decently tested. Our industry has low quality standards it seems. But creating something that will cause confusion among the less skilled in hoping it will help the experts do fewer mistakes is not a good trade off: IRL teams have one 10x programmer for many more regular ones, if at all.
Again, I follow the logic. I just think it's not a good bet for the community. It may be a good bet for FB scale entities, but I'm not even sure it is.
You could already do that with regular functions, class inheritence, mixin, prototype inheritence, composition, event dispatching or stores.
If preventing people from being confused and doing the wrong thing was the goal, I'm not sure adding one new way to the mix is going to make things clearer.
Besides, while I agree tooling help with applying good practices, including encapsulation, it's no substitute for a good initial API design.
React and JS API are confusing, because they have been designed this way from the start. We are now adding things on top of it, again and again, without ever fixing anything at the bottom. This creates problems at the same time it solves others.
Another issue is that the JS community wants to professionalise without aknowledging that a huge part of it doesn't have the skill to do so yet. It's a community that includes many young devs with little experience, people that are not programmers but ends up doing so, devs born in a culture of instant results... It's important to address this as well, by talking to them in tutorials and documentation, by creating API shaped with them in mind, so that they can grow in empowering directions.
Instead, we create monster trucks, and they put ads on youtube to tell everyone how "easy it is to drive" and "you should do it too right now".
For me, hooks are a monster truck. And most JS devs I work with are not capable of driving that safely.
Sure, but if you can drive hooks safely, they seems to make some things _very_ clean. I'm going back through and rewriting a toy app I haven't launched yet to use hooks and it's been a joy to work with them so far.
This seems to be the response to every addition to javascript or react without addressing the above concerns.
Nothing wrong with your comment on trying to embrace it per se, but it would be healthier if this sentiment was balanced in the community with more skepticism rather than blind embrace.
One of the key reasons for choosing a framework/library is to enforce (reasonable) constraints. These constraints help in making sure that the framework takes a longer term view of things than just making it easy in the short term.
>to me, separating out that function is a good thing
To us, too, and that's exactly the point of Hooks. They let you extract logic into functions in a way that wasn't possible before. I suggest to read more than a single page -- in particular, extracting custom Hooks is largely the point of the proposal.
Can't you achieve the same result by leaving only view logic in the component, and having the data-related logic, including the fact that data has changed in a way that may require redraw, handled in a separate object? Here's how I'd do it in Mithril/TSX:
class WidthStore {
width: stream.Stream<number>;
constructor() {
this.width = stream(window.innerWidth);
window.addEventListener('resize', () => {
this.width(window.innerWidth);
m.redraw();
});
}
}
const widthStore: WidthStore = new WidthStore();
class MyResponsiveComponent {
view(vnode) {
return <p>Window width is {widthStore.width()}</p>;
}
}
The problem is class based components have to be written very carefully to remain testable, and the average developer is not that careful. It's basically a foot cannon, and the worst react spaghetti I've seen has always been a result of huge classes that manage way too much state. I believe that making it a convention for developers to break up their components into small, pure functions will raise the quality of most react applications. Recompose has made this possible for a while, but most react devs aren't familiar with it, and baking it into the framework should make that approach less exotic. Of course, you will still be able to write huge functions that manage too much state, but I think classes encourage this more than functions.
The article you link to actually explains that quite well. Basically there are three motivations for hooks:
1. Keep code that belongs to one functionality in one place. For example setup and teardown would be in the same hook, but when writing a class they are scattered among the many things happening in the event methods in the class
2. Allow new ways to compose functionality. You can use the same hook in different functions. You could achieve the same effect before, but this makes it more convinient
3. Produce code that works better with Prepack [1], to make ahead-of-time compiled react runtimes more efficient. It might be some time until this becomes a rolled out advertised feature, but hooks are a good step on the way there
I think this in turn is a symptom of conflating rendering with state management in the first place.
The line between React and vanilla code is blurring more every day - which is a bit greedy for something that's purely meant to be a rendering solution. I would personally advocate to push React as far away from my app code as possible, and instead implement a specialised container class that hooks into React's internals (Controller? Model?) purely to handle localised state changes.
This makes me very skeptical about the proposed feature in React, called "hooks", which is linked to in the article. It lets you add state to your functional components, and it looks like you end up bundling all your code into one function rather than having a separate constructor to initialise the state (to me, separating out that function is a good thing). I would be interested in the motivation for that.
Link: https://reactjs.org/docs/hooks-intro.html