2 ms·
You know, i'm not even sure that hooks were worth all of the problems with maintainability and readability that they've caused. I don't have the slightest doub
by KronisLV 5y ago
You know, i'm not even sure that hooks were worth all of the problems with maintainability and readability that they've caused.
I don't have the slightest doubts about me being in the minority here, but i've seen a large amount of projects which attempt to use multiple state hooks per component, and as a consequence the dependency arrays become brittle as the code is changed and sooner or later you're stuck with your page being in an endless rendering loop, because your logic isn't clever enough to actually untangle all of the state to decide when it needs to change anything:
useEffect(() => {
... // a whole bunch of code
}, [foo, bar]);
useEffect(() => {
... // a whole bunch of code
}, [bar, baz]);
useEffect(() => {
... // a whole bunch of code
}, [foo, bar, baz]);
Sure, you can be responsible with that stuff when you're the one writing the code, but when you open up someone else's project and have "the business" breathing down on your neck but have to untangle their uncommented code, you feel like some of the features are footguns in disguise. At least with shouldComponentUpdate all of the code that decides whether something should be done was in one place.
You could easily comment that code out or change it. But with hooks, you need to untangle how all of the related calls to setState work and where every method for every state hook is called and why. I'm not sure that it was a good idea to decouple those.
- oaxacaoaxaca 5y agoFor a good while I thought I was the only one who is against hooks. It's good to see there are two of us. By the looks of the other comments here, maybe even three.
- reactspa 5y agoHooks never grew on me. I pretty much stopped paying attention to new versions after React 14. KISS - keep it stupid simple. I suspect that some Devs new to JS didn't like the various definitions of "this", and Hooks was supposed to help them out.
- azangru 5y ago> I suspect that some Devs new to JS didn't like the various definitions of "this", and Hooks was supposed to help them out. No, stale closures caused by hooks are more confusing than what "this" has ever been, especially since this-related problems are mitigated with fat arrows and class property assignment. No, as far as I understand, the driving force behind the hooks was the vision of the coming concurrent mode, for which class components posed some difficult problems somehow.
- lhorie 5y agoThere are a number of people that dislike hooks, many of who are vocal in React threads. Basically the entire classes-are-fine camp do, and there are a few of us in the "the React team doesn't appear to understand the functional paradigm" camp. I fully expect that in a few years React will be widely seen as a J2EE-like poster child of over-engineering shark jumping for the functional paradigm. I already do.
- city41 5y agoI find hooks are best when used sparingly. I once worked on a project that went all in on hooks and some bugs were very hard to track down. Stale closures can be a headache too. I've been meaning to capture the gotchas I've seen into a website. Maybe I will one day. All in all, hooks get the job done but I'm not really a fan.
- gherkinnn 5y agoIt's tricky. I've had some nasty stale closure bugs too. The ESLint hook plugin fixes these, but I wish that plugin wasn't required. And some of the hook rules are puzzling at first. But, I've had way more annoying problems using class-based syntax. Twice the code, four times the pain. And TS type inference doesn't work as nicely with classes. Vue got it right in many ways. At least back in the 2.0 days, the last I've worked with it.
- the_other 5y agoI’m with you. They’re confusing. The magic is too high. They maintain state in an invisible way. The abstractions are hard to follow, especially when you roll your own. The key issue for me is that they hide the rendering lifecycle from you. Everything’s implied. One of the complaints with classes was that you had to learn the arcane weirdness of the lifecycle. But a) it’s not that weird and b) it’s much easier to learn when the callbacks are named after the stage in the lifecycle. The hooks way makes all that invisible. That said, I’m quite fond of the ‘[value, setter]’ return type from useState. It’s nice to use and nice to write. Just don’t ask me to explain how it works for multiple re renders.
- kabes 5y agoYeah, and sometimes it feels like I'm writing a really cumbersome dialect of javascript. I mean, something simple like: let i = 0; const inc = () => i+=1; becomes: const [i, setI] = useState(0); const inc = useCallback(() => setI(currentI => currentI + 1)); Every single thing needs layers of abstractions upon layers of abstractions. For all the hate angularJS got, at least with dirty checking your javascript was just plain javascript. I'm leaning more and more towards svelte, which offers this, but more performant than with dirty checking.
- axiosgunnar 5y ago> const inc = useCallback(() => setI(currentI => currentI + 1)); This might actually even have a bug and would need to be even longer to properly function :-D I think you need to add [i] as a dependency, no?
- kabes 5y agoNo. I'm using a callback in the setter which gives me the latest i and the setter never changes. If instead I would use setI(i+1) I'd have to add i as a dependency, but since state updates happen asynchronous, this would have a bug when calling it multiple times before the state is flushed.
- 5Qn8mNbc2FNCiVV 5y agoThe useCallback is redundant, the rest is still valid but I'd rather have it this way than magical variables where a reassignment makes the framework do work. This way I can just find all references of "setI"
- 9wzYQbTYsAIc 5y agoYou can still use class components where you feel the need.
- ng12 5y agoPeople can write bad code in any framework. If it's that difficult to uncoil declarative state in your head the component is poorly written, hooks or not.
- kiliancs 5y agoHooks are a response to a very specific need. They do wonders in terms of what you are able to accomplish by allowing you to encapsulate side-effects and state management. If you are writing complex or large applications, the ROI is clear. Now, there are obviously bad ways to use (no pun intended) any tool. Doing things right requires some planning, and learning some patterns. Many effects that also potentially relate to each other should be encapsulated into custom hooks, for example. And it's often a mistake to just make everything hook-dependant—think about how would a non-react bit of the page interact with this feature, or how can you unit-test without dealing with state and component lifecycles. Learning how to do this in a way that is approachable, maintainable and that closely follows the domain model is not necessarily easy, but that is true for almost every aspect of software engineering, including how to organize functions or classes. The same is true for things like Suspense. Again, if you have worked on a large application, you'll see that managing side-effects, data that comes (partially or fully) from a backend, and providing a clean and performant experience (no cascading, reasonable errors) is hard. Suspense answers to a real need. Whether you like the solution they propose or not, that there's throwing of Promises involved is, honestly, an implementation detail—and I'd say it works great. And if these features are not for you, don't use them. And if React is not for you, don't use it. If you have to work on a codebase that is not well architected, full of tangled useEffects, you'd probably have a similarly bad experience if the application was class-component-based or built using a different framework.