I wanted to like React so bad. I tried. I loved JSX and really appreciated the way you could reuse components. That was all very cool, and I was initially quite enthusiastic about it. But for whatever reason, I just could not figure out state management/hooks. Drove me crazy. It just always felt so unnecessarily complicated compared to other languages and frameworks I've used (even vanilla JS). Now, don't get me wrong: I fully accept the blame here. I am mostly self-taught (and not even the best 'student' in that context, haha) so I'm sure I just lack the overall knowledge base/big-picture understanding to really appreciate what they've done here. I hope I'll give it another shot one day, and perhaps with fresh eyes (and maybe with the help of a patient tutor), it will all 'click'!
paulddraper|2 years ago
I'll draw an analogy.
---
Why did async/await replace callbacks? They are really the same thing, aren't they? Aren't callbacks good enough?
Async/await allowed programmers to write asynchronous code as if it were synchronous.
---
Why did hooks replace classes/imperative? They are really the same thing, aren't they? Aren't classes/imperative good enough?
Hooks allowed programmers to write stateful code as if it were stateless.
This is functional code, without scary, hard-to-reason side-effects. Except for one limited part, which operates in a stateful way.I argue that this is simpler than the equivalent imperative-DOM modification code, and the gap between these only increases with real programs.
This isn't just a weird "web bro" thing; the hooks paradigm is useful (in theory and practice) to every UI platform.
I even wrote an implementation (closed source) for hooks in Angular. It was lovely.
imtringued|2 years ago
It is some pseudo DSL with hidden hard to reason mutable state.
xxbondsxx|2 years ago
It also shows that although there might be some learning investment required to use the more modern version of both, it's well worth the effort. I can't imagine going back to callback-riddled javascript
bernawil|2 years ago
skydhash|2 years ago
I don't know exactly how – never had the time to properly research it – but, my current guess is that the hooks code taps into the scheduler/dispatcher – which handles the execution of the function representing the component – and stores value and logic somewhere. It uses the order of these calls as keys – you don't have to specify them – and provides the stored values as return values of the call of the hooks functions.
Hooks are escape hatches from the functional paradigm of React's components. You are always providing new values, and it decides when to store the updated version – mostly based on the deps array. You then get back what you stored. On the surface, it's still basically functional, but the actual logic is not. It's more like a repository of code and values.
WorldMaker|2 years ago
It's still so very functional programming-inspired, even if the execution engine (scheduler/dispatcher) isn't that much like the Monad runtimes of most functional programming languages and the various Hook "monads" don't get captured in even the return type of functions (much less the parameter types) and get elided away. (It could be more "traditionally JS monadic" if it [ab]used async/await syntax and needed some fancy return type, even though the concepts for hooks don't involve Promises [or Futures, being the slightly more common FP Monad name]. Though also, from Typescript patch notes, I've heard React is exploring [ab]using Promises for something like that in the near-ish future.)
Monadic bindings needing to be in-order, just the like "Hook rules", isn't even that strange from an FP perspective: there can be a big difference in which of two Promises is awaited first. There can be a big difference in which IO binding executes first (you don't want to input something before the prompt of what to input is printed).
imtringued|2 years ago
super256|2 years ago
tomcar288|2 years ago
moffkalast|2 years ago
paulddraper|2 years ago
"What's this .map() nonsense? The indexed for-loop always made sense to me."
yamtaddle|2 years ago
qudat|2 years ago
That’s the magic of react. The problem is no longer manually managing transitions between state but state itself.
That’s why state management is so critical in the react ecosystem.
Further, react has delegated two key features to userland: side effect and state management.
Personally, I don’t want react to solve either of these problems because it’ll just turn into the disaster that is react server components: feature development driven by corporate interests (eg vercel).
recursive|2 years ago
If this was actually how it worked, I'd have much less problem with react. What I mean, specifically, is that not all function dependencies are explicit. This makes it look like the state is passed into some function. And then the view is returned, depending only on state. In reality, half the state is passed in (as in the argument to a function call), and half comes out of some mysterious hook storage structure. If the state was really a function argument, you could easily inspect the whole state in a debugger. Instead of... I'm not sure how you'd actually do that.
switz|2 years ago
if you've followed along with the react team's discussions on server components, it is very clear that vercel implemented the react team's vision and less so the other way around.
as someone who has been using them extensively, I understand why. they're delightful.
vercel does control next.js which is the only framework to completely implement RSC, but as other frameworks catch up, RSC will have a wider surface area.
june_twenty|2 years ago
fendy3002|2 years ago
Hopefully you'll click on it someday
preommr|2 years ago
2) Components have behavior. In Class based components they were implemented as methods. Simple enough, classes have methods. If you think about an iteration of rendering the ui tree, it goes down the tree and calls the mount method for each component in the ui. With hooks, instead of calling a method on an instance, it's implemented as an inner function of a component that is also a function instead of a class. Instead of explicitly calling the mount method on a class instance, calling a function that's a component automatically runs it's inner mount method. The way that it knows the which inner function is a lifecycle hook is because you import something like 'useEffect' from the react library. And that global useEffect function knows the current component because the renderer sets it as it's going down the ui tree. Hooks are better because they can be written as arrow functions (more concise, cleaner), and because you're calling a framework function, that function can have more complex behavior like how useEffect can track when to update because it's being passed in an instance of something like an internal state variable.
ianbicking|2 years ago
dqh|2 years ago
https://nakedjsx.org/documentation/#getting-started
EDIT: clarity
caditinpiscinam|2 years ago
unknown|2 years ago
[deleted]