How to derive "loading" from useSWR between fetches without revalidation?

Viewed 5422

I was asked a question regarding SWRs "loading" state:

How do you create a loading state from SWR between different URL fetches?

Their docs make it appear straight forward:

  const { data, error } = useSWR(`/api/user/${id}`, fetcher)
  const isLoading = !error && !data;

However, this logic seems to fail after the first render of the hook/component. On the first render data is undefined. Then loads and data becomes a value to consume in the UI.

Let's say I change the id via the UI and want to show loading indicator. Because data is no longer undefined, the same logic fails.

There is an additional item returned isValidating. So I updated my logic:

const isLoading = (!data && !error) || isValidating

However, this could be true when:

there's a request or revalidation loading.

So in theory something else causes my component to rerender. This could inadvertently cause a "revalidation" and trigger loading state gets shown. This could break the UI temporarily, by accident.

So how do you derive "loading" between URL changes without revalidation? I am trying to replicate how graphQL Apollo Client returns const { loading, error, data } = useQuery(GET_DOGS);

1 Answers

Let's say I change the id via the UI and want to show loading indicator. Because data is no longer undefined, the same logic fails.

data will be undefined again when you change the key (id), if it doesn't have a cache value.

Remember that in SWR { data } = useSWR(key) is mentally equivalent to v = getCache(k), where fetcher (validation) just write to the cache and trigger a re-render.

data is default to undefined, and isValidating means if there's an ongoing request.

Related