Hacker News new | ask | show | jobs
by lloydatkinson 1552 days ago
I agree with this article, when I’m doing frontend development I much prefer to use Vue - with its options API (I ignore the composition api as it’s essentially a clone of reacts hook system).

But when I do any react such as assisting another team using it, I am constantly surprised and reminded just how much of a bad developer experience react hooks are.

The coupling of needing to constantly be aware of the intricacies of rendering while also balancing reactivity and data binding leads to probably the most offensive API I’ve ever had to use.

When writing useState or useEffect etc the not always required last argument is a damn array or empty array or sometimes an array with several items.

What does not passing an array mean? Well, I’m sure someone could explain at great length the complexity and alleged need for this but anyway: passing nothing as the last argument of useEffect results in an infinite loop.

Passing an empty array means “don’t render again until actually needed”.

The third option of passing a variable length array results in something else entirely I still don’t understand. Every article does it slightly different.

Ultimately what this leads to for me at least is a developer hostile API full of seemingly intentional foot guns. The other day I had the situation where useEffect to call an API resulted in calling the API endlessly and constantly. Then I thought “ah I have seen this before, it means I have to pass an empty array”.

It’s absolutely infuriating and smells of a bad API design. What happened to the importance of DX (developer experience)?

As I said I’m sure someone could hand wave away the alleged need for this complexity but honestly it simply feels like a bad API. No one will ever convince me that an empty array vs no argument is “functional” because functional code values making side effects and purity deliberate decisions with a focus on clarity.

How do other frameworks let you fetch from an API? Generally a simple assignment and await statement.

2 comments

No array means execute the hook on every rerender of the component.

Empty array means execute the hook once on initial render.

Non empty array means execute the hook when the value of anything in the dependency array changes.

These are pretty simple to remember imo.

An alternative design could have been to pass in an object as a second parameter instead of an array with these options details like

  { runOnlyOnInitalRender: true }
Or

  { alwaysExecuteOnRerender: true } 
Etc. But that feels far more verbose than the three options we have now.
> These are pretty simple to remember imo.

But why should we? No other reactive framework makes the developer go through this ritual. Even RxJS is clearer to understand.

> Etc. But that feels far more verbose than the three options we have now.

A better designed API would require neither.

The composition feels a lot closer to the "ratom" concept from the Clojurescript ecosystem (https://github.com/day8/re-frame/blob/master/docs/flow-mecha...) than it does hooks. I don't hate it at all.