1. 47
  1. 9

    This is well written and I agree with a lot of it but I’m certain the author doesn’t understand the benefits of hooks and it colored a lot of the content.

    I’m in the firm “composability over inheritance” camp and I think sharing behavior via functions is a drastic improvement over class inheritance.

    Best practice class-component composition was done with higher-order components, not class inheritance, and it was a nightmare. So yes, hooks are easier to compose.

    But the things that hooks made 99% better were: incorrect reactivity (eg only a small fraction of class components correctly reacted to their props) and side effect cleanup. I don’t think most React developers realized how buggy their components often were. Link me to any non-trivial React component’s source and I bet I can point at such a bug.

    Unfortunately hooks are much harder to understand and read, and they have too many footguns. I don’t think they’re the final api. But they are a huge improvement over class components because they are much more bug free.

    1. 3

      What do you think about the ‘signal’ approach described later on in the article?

      (Also is it just me or are signals just functional reactive streams…)

      1. 3

        Angular, which is listed in the signal group, is based on RxJS, which is pretty explicitly FRP-based. The state management libraries we end up with in the ng ecosystem are mostly “just” organization tools and QoL improvements over using the observables already provided - see https://ngrx.io/ and https://opensource.salesforce.com/akita/

        [1] https://rxjs.dev/

        1. 2

          It all depends on the specifics, and I don’t know Solid’s implementation well enough to have an opinion. KnockoutJS had the best implementation of this type of data binding a decade ago and no one has really caught up to my knowledge.

          My current work codebase uses jotai which is in the recoil family of data management and I’ve come to loathe it. Jotai atoms look similar to these signals (automatic dependency tracking, computed/derived values, can be used anywhere in the tree). shrug

          1. 1

            I’d be curious to hear more about your experiences with jotai if you’re willing to share :)

            1. 1

              I honestly just don’t get the Recoil family of state management. It has exactly one real benefit over React context: you can subscribe one component to one piece of data. With React context, if you read anything out of the context, you rerender on any change to anything in the context, even what you didn’t read. That is why Recoil was invented. It’s the only reason to use it (until React fixes the performance issue and let’s you subscribe to a subset of context).

              But I think most people reach for recoil/jotai because they have a visceral aversion to passing props through components and would rather just reach for global state. But by defaulting state to global state you’re defaulting your components to being singletons.

              As for jotai specifically: the docs/API suck (tell me if any of this makes sense to you: https://jotai.org/docs/utilities/family) and I’ve hit state-tearing bugs which is a huge red flag.

              I’ve worked in a codebase that used Recoil and Relay and the Recoil just made all the Relay unidiomatic and impossible to scale.

      2. 5

        Good article.

        I really do question the benefit of react itself deciding when to re-render. I’m certainly not against declarative HTML templates, but when projects get bogged down in trying to track down excessive re-rendering issues, I have to question whether the juice is worth the squeeze with the abstraction.

        1. 2

          I think React completely lives up to the promise that it had several years ago, which is: your UI is a function. Everything else is handled for you. Does that come with a performance penalty sometimes? Yea. I personally have never (I mean never) had a situation where when I dug into it, that was what was at fault. I don’t work on games, I don’t work on 3D map libraries, I work on information systems. I just need to display the current contextual data to the user, and it’s usually not very much.

          React has been 1,000x better than mobile SDKs (i.e. iOS UITableViews) and jQuery there. Your mileage may vary. It’s not perfect, because software can’t be perfect. But, it definitely is fine, and mostly stays out of my way.

          1. 2

            I had the privilege to attend the first react conference. I was and am a JS dabbler at best. Recently after years and years very far away from JS, I got into a React app, and found that instead of… improving? It got a lot more complex, easily all centered around hooks and specifically the cryptic multifaceted useEffect() hook. The real pity of these frameworks isn’t that they’re bad, they’re not, it’s just that they have almost infinite footguns and zero typesafety or compile time checking. Not to mention the errors that do come from webpack can actually break things if you follow them (ie it will tell you to add a variable to the optional useEffect array which will start a infinite loop).

            1. 1

              To nitpick a bit, the form example is overly simplified since it doesn’t do anything to justify rendering the inputs as controlled components. In the example, one could easily replace the the useStates with useRefs, avoiding the re-rendering concern. The example should be expanded to actually do something with the state to justify it.

              1. 1

                I’m not super into the rant aspect of this but the discussion of details of how state updates propagate is very good.