DEV Community

Joanna Otmianowska
Joanna Otmianowska

Posted on • Edited on

Status instead of isLoading boolean?

When I saw the article 'Stop using isLoading boolean' written by Kent C. Dodds my first thought was - what's wrong with isLoading boolean? Why shouldn't I use it? Then I read it. And saw his point.

It is a common practice to use isLoading boolean to show some placeholder or spinner when data in our app is loading. This is fine - you set isLoading to false, change it to true when data is loading and when data is here - put it back to false. But what happens when error occurs? Data is not loading but there is no data to show either. We start to add more conditions - first not loading and no error, then for not loading but with error, another one for loading. Do you see the point?

What Kent suggests in his approach is having status with different enum values for every case e.g. 'idle', 'resolved', 'rejected'. In the code then we can go like (examples based on the article that I mentioned earlier):

if (status === 'idle') {
    return <div>Data is loading...</div>
}

if (status === 'resolved') {
    return <div>{Fetched data}</div>
}

if (status === 'rejected') {
    return <div>Something went wrong!</div>
}
Enter fullscreen mode Exit fullscreen mode

Thanks to that we can set status for particular case after every activity and there is no need for double conditions (like is not loading and there is no errors etc).

To get rid of equal signs we can put status info in variables.

const isLoading = status === 'idle';

if (isLoading) {
    return <div>Data is loading...</div>
}
Enter fullscreen mode Exit fullscreen mode

And that's it! I recommend reading Kent's article for deeper explanation and more examples.

Latest comments (43)

Collapse
 
asafagranat profile image
Asaf Limi Agranat • Edited

In my opinion you are over simplifying what in reality is mostly a complex matter. To begin with, you might be responsing to a particular article, but in your own standalone article you are not specifying what action you are performing for which you are calling the isLoading status in the first place. I can only infer you are refering to a fetch operation, given the scenrios you lay out. But isLoading is used in many different use cases that have multitude of scenarios of different complexities. You could be loading a new view, refreshing part of the UI, loading pre-fetched data, calculating post action etc. isLoading as boolean is very valid for those many scenarios, and does not correlate to response statuses.
Other than that, isLoading is self-indicative by its name, while the other statuses you exemplify are more abstract in meaning and require closely-coupled context to know how to use them. Self-indicating statuses are to be appreciated, even being boolean. The verbosity of having to check multiple statuses together in order to know how to act on them is not a bad thing, is not anti-pattern, and I'd even dare say they are desired. In the end of the day, we all just want clearly read code, especially when it's someone else's.

Collapse
 
joannaotmianowska profile image
Joanna Otmianowska

I am not saying that isLoading is always bad. I just wanted to share what I learnt in the article I mentioned. That is really interesting to me because earlier I really didn't even think that in some cases isLoading boolean may be not the best choice

Collapse
 
mrdulin profile image
official_dulin

If you don't want to add extra words - "idle"

Just consistent with the state of the JavaScript Promise.

A Promise is in one of these states:

pending: initial state, neither fulfilled nor rejected.
fulfilled: meaning that the operation was completed successfully.
rejected: meaning that the operation failed.

Collapse
 
jochemstoel profile image
Jochem Stoel

It is my opinion that every developer who implements a Boolean isLoading is not a competent developer.

Collapse
 
andrewbaisden profile image
Andrew Baisden

Good tip this is a great way to deal with it.

Collapse
 
sandromaglione profile image
Sandro Maglione

If you are into functional programming, this is the perfect situation for using a union-type. There are some great libraries in typescript to implement union-types. I am using @practical-fp/union-types, check it out!

github.com/practical-fp/union-types

Collapse
 
c5n8 profile image
c5n8

I made a package around this idea for Vue.
github.com/c5n8/vue-use-async-hook
The challenge is to name the state when we have not called the function for the first time. I call it standby, but I think it could be better.
Also, if only Javascript/Typescript has implicit member expression like Swift, we could eliminate these space hogging strings, masquerading as a pseudo enum.

Collapse
 
sgolovine profile image
Sunny Golovine

This article makes me feel very (type) unsafe. But seriously, I would not recommend this route unless

  • You use Typescript
  • Store each status as an enum.

The big issue I have is the inevatable instance where you spell 'loadng' instead of 'loading' and your logic breaks. This can be avoided using union types in typescript of creating an enum with regular JS.

Collapse
 
maciekgrzybek profile image
Maciek Grzybek

That's why we should all move to TS :) oh and also I'd recommend union types instead of enums

Collapse
 
larsejaas profile image
Lars Ejaas

It might be great for some situations but more verbose for others...

Let me explain.

Normally (in React, but I guess it would be almost the same elsewhere) I would import the fetch logic like this:

const [isLoading, Data, isError, Error] = GetData(URL)

Then in the JSX:

{!!isLoading ?
(<div>Data is Loading</div>)
:
(!!isError?
(<div>Something went wrong</div>)
:
(<div>Data</div>)
)}
Enter fullscreen mode Exit fullscreen mode

My point is that the booleans make it possible to use really short syntax.

I definitely see your point when status could have a lot of different states, but if you have a lot of different skeleton loaders and stuff I think booleans are hard to beat.

why not return the different states like booleans?

something along the lines:

const [iddle, resolved, rejected] = GetData(URL)
Enter fullscreen mode Exit fullscreen mode
Collapse
 
tojacob profile image
Jacob Samuel G. • Edited

In Typescript I always use enums for that :)

Collapse
 
aryangomes profile image
Aryan Gomes

Thanks for the tip and for sharing!