Hacker News new | ask | show | jobs
by csande17 2055 days ago
One thing that feels off about hooks to me is the "primitive" ones React provides. Like, here are the basic things that hooks can do:

1. Tell the component to re-render

2. Store an object that persists between component renders

3. Run something after the component has been rendered

4. Run something when the component unmounts

React doesn't give you functions that do these operations individually. Instead, you get weird hybrids like useState, which combines storing a value with telling the component to rerender when the value changes. So you sometimes have to jump through hoops to get the behavior you want. (Well, useRef sort of does (2), except it constructs the object itself.)

2 comments

I don’t understand this complaint.

Components are functions of their props and state, returning markup (in the form of a descriptor foe the rendering engine). When a prop or piece of state changes, the component must re-render. The fact that useState might be responsible isn’t relevant.

That said, I’m also still struggling with hooks (and I like functional programming in JS). I want to like that hooks let you wrap your domain logic into neat bundles, but I find that I miss the lifecycle callbacks of the older class based style.

Hooks based components are trying to make modules that are “about” the problem domain they illustrate, but they do it as a feature of React. React isn’t about your problem domain, it’s about driving the DOM and rendering, and I think it makes more sense to treat React code that way.

I’m open to having my mind changed on this. I have spent way more time writing classical React than hooks-based.

> Hooks based components are trying to make modules that are “about” the problem domain they illustrate, but they do it as a feature of React. React isn’t about your problem domain, it’s about driving the DOM and rendering, and I think it makes more sense to treat React code that way.

This is why I think it's going to take a bit more time with hooks code to realize the opposite to csande17's complaint is really true: the problem with the hooks React ships with is not that they aren't primitive enough (as the sibling comment points out, csande17 probably is also missing that some of the primitives they are looking for expressly don't exist as React hooks because they don't fit the algebraic effect model React is moving toward, versus the lifecycle model React is moving away from), but instead that the hooks React ships with are still (or least feel) far too primitive an algebra for the "calculus" needed for at least some problem domains (if not most problem domains).

I don't specifically have any answers for what the next layers up will be, though I appreciate this article for trying to explain how algebraic effects work in other languages because that provides ideas from other places of how their primitives get composed.

> but I find that I miss the lifecycle callbacks of the older class based style.

Why not continue to use the class based style? It's still supported. We're using hooks for some simpler cases where they really cut down on boilerplate, but we're continuing to use classes for more complex cases where we find it more readable.

That's what I did at my last gig, where I owned the codebase. At my current gig, I share it with 10 people and the decision to move to hooks was made before I joined.
I don't think hooks can actually do 1, 3 and 4. Components re-render whenever React feels like it's a good moment to do so. That happens to include "when state changes", but you're not able to rely on that. This will supposedly become more apparent once Concurrent Mode finally lands.

(You can certainly fault React for it being hard to grok the "correct" mental model, but it makes sense that its primitives do not match the wrong mental model to me.)