Issue
I was asked a question regarding SWRs "loading" state:
How do you create a loading state from SWR between different URL fetches?
href="https://swr.vercel.app/getting-started#quick-start" rel="noreferrer">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);
Solution
Let's say I change the
id
via the UI and want to show loading indicator. Becausedata
is no longerundefined
, 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.
Answered By - Shu Ding
Answer Checked By - - David Goodson (ReactFix Volunteer)