
Stop Using IsLoading Booleans - valtism
https://kentcdodds.com/blog/stop-using-isloading-booleans
======
_bxg1
I have mixed feelings about this. In a language with proper enums like Rust
this is certainly the way to go, because your entire data structure can be
tied to which state you're in (Success would _only_ contain the position,
Rejected would _only_ (and always) contain an error, Loading would _never_
contain redundant data). In Rust you would also get the benefit of having
match { } make sure you always take care of every possible variant.

In JavaScript, on the other hand, code could just as easily set an error and
forget to set the status as set an error and forget to clear the position.
There's still some overlap between state info and there's not a singular,
clear winner between the two patterns.

Here's what I would do for this case: first, move the error rendering clause
above the position one. Erroring, like loading, is an exceptional status above
the "normal" status. Therefore the position should be the "fallthrough"
branch. This change alone would fix the actual problem demonstrated.

Then, to help avoid inconsistencies, I like to put my "isLoading: false" in a
"finally" clause (if it's on a Promise), or some equivalent. Unfortunately
watchPosition is a bespoke function with regular callbacks instead of a
promise, but you could still centralize the loading flag clearing in some way.
Or maybe "promisify" that function with a new Promise((res, rej) => {}).

Certainly if you have more than just these three statuses you start getting
into territory where a status string makes more and more sense. However, these
three (success, error, loading) are special, and in a large number of cases
they're all you have, so they can be afforded some special treatment.

~~~
gwillz
Is this something typescript could fix? I've written a fair few union types
with discriminants that work in the same way as rust enums.

The trick though is to declare the redundant fields as undefined for every
overlap case.

~~~
_bxg1
Possibly. I've had trouble getting TypeScript to discriminate object unions in
the past without manually writing type guards, which are cumbersome. This is
one of the few things Flow is actually better at.

------
Nullabillity
At this point I'm starting to think that every state framework should ship
with something like Diode's Pot[0] (which this post also reimplements, though
with more strings and without the clear state diagram).

[0]:
[https://diode.suzaku.io/advanced/Pot.html](https://diode.suzaku.io/advanced/Pot.html)

