Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

cache-and-network shows loading true when pulling from cache #2601

Closed
lukepighetti opened this issue Nov 19, 2018 · 13 comments
Closed

cache-and-network shows loading true when pulling from cache #2601

lukepighetti opened this issue Nov 19, 2018 · 13 comments

Comments

@lukepighetti
Copy link

Hey everyone,

this probably needs comments from the team and community, so I will just mention it and see what people think.

Currently, if you're using cache-and-network fetch policy it works like this

first load: loading: true, data: {}
second load...
  cache: loading: true, data: { data }
  network: loading: false, data: { data }

This personally lead me to stop checking for the loading condition when using cache-and-network. But, then you lose the ability to check for first load.

My only solution was to check like this

if(!Object.keys(data).length) {
   return <Loading/>
}

This doesn't make sense to me. You should be able to switch out fetch policies without refactoring your app.

if(loading){
  return <Loading />
} 

return <Component data={data} />

Should work no matter what the cache policy.

@OHUSAR
Copy link

OHUSAR commented Nov 20, 2018

Just checking, but don't you need to pass the notifyOnNetworkStatusChange prop to Query component? Because otherwise your component won't get rerendered on network status change and you won't be able to proprely detect loading state.

e.g.

 <Query
     query={query}
     notifyOnNetworkStatusChange={true}
    >

@lukepighetti
Copy link
Author

lukepighetti commented Nov 21, 2018

Hi there, I haven't tried that prop, just learning about it now. My components were rendering twice, once from cache and another from network without that property. I don't know how that property affects things, then. Just more questions. I'll have to try it after the long weekend.

@JoviDeCroock
Copy link
Contributor

JoviDeCroock commented Dec 29, 2018

cache-and-network applies a networkRequest to refresh possibly stale data. In essence we should have something like if (inCache) reloading = true else loading = true. So the programmer gets notified that there is a networkRequest but stale data can be shown.

@hwillson are there any architectural plans about this or?

@Emiliano-Bucci
Copy link

@JoviDeCroock I think i'm having some issues with cache-and-network (or maybe not) but i have a doubt: is correct that even if the data from the network request is the SAME that the one in the cache, Apollo updates anyway the cache?

@JoviDeCroock
Copy link
Contributor

JoviDeCroock commented Feb 9, 2019

Yes, this would require a deep equality check which does not seem to happen. Don't take this answer as a definite though, I think @benjamn can give a more definite light on this.

@Emiliano-Bucci
Copy link

Emiliano-Bucci commented Feb 9, 2019

@JoviDeCroock But the fact that apollo updates the cache anyway is the correct behavior? I think not, otherwise what's the sense of using it (cache-and-network) if apollo will update the cache (and consequently unmounting and remounting your components)?

@hwillson
Copy link
Member

hwillson commented Sep 6, 2019

React Apollo has been refactored to use React Hooks behind the scenes for everything, which means a lot has changed since this issue was opened (and a lot of outstanding issues have been resolved). We'll close this issue off, but please let us know if you're still encountering this problem using React Apollo >= 3.1.0. Thanks!

@hwillson hwillson closed this as completed Sep 6, 2019
@sincospi
Copy link

Here is a solution that involves manually checking the cache to see if data already exists. Hence you only show loading state on first query (hooks implementation)

@s-h-a-d-o-w
Copy link

@hwillson The behavior with 3.1.2 is just the same like it used to be. loading is true even if the data was already retrieved from the cache.

@sincospi I'd recommend looking into whether this workaround works for your use case, since it uses things that React Apollo actually already provides: apollographql/apollo-cache-persist#42 (comment)

@sincospi
Copy link

sincospi commented Dec 22, 2019

I'd recommend looking into whether this workaround works for your use case

Thanks for the link @s-h-a-d-o-w . That solution won't work for networkStatus === 2 situations where query variables change. You have to query the cache.

@levrik
Copy link

levrik commented Mar 12, 2020

@hwillson Why is this issue closed? This is still an issue and reading from the cache doesn't really sound like the real solution.
I have a component which gets an ID passed. Then the component queries the data. If the data changes, it has to fetch again. In case the new ID was already loaded and is in cache, the results are returned from the cache and since I have cache-and-network globally set, it fetches again in the background to make sure the data is up-to-date. There is no way for me to distinguish between the initial load and a refetch of the data. Since loading of the data can take 1-2 seconds it is crucial to be able to show a loading screen on first load.

@ardok
Copy link

ardok commented Apr 3, 2020

Like what @levrik mentioned. I feel like if I were to use cache-and-network, might as well use network-only because of the loading flag.
Ideally, loading should be true only if you're fetching data from the network.
Having another flag to indicate that we're using data in cache but still loading from network would be nice.

In my mind, I want my UI to not render loading state if I were to show data from cache, but in the background it fetches the latest data. Once the latest data is fetched, the data on the UI just changes automatically.

Like OP said as well, "You should be able to switch out fetch policies without refactoring your app.".

@arvindell
Copy link

I wrote two custom hooks that rewrite the loading property in order to enable this behavior. You can find them here: https://gist.github.com/alexvilchis/64a5b07172e8e216c6542f4f4b637cdd

They simply check the cache and set loading to true if it didn't find an entry.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants