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

Update queries that are no longer active, but the results are cached #419

Closed
bradjabel opened this issue Jan 15, 2017 · 6 comments
Closed

Comments

@bradjabel
Copy link

bradjabel commented Jan 15, 2017

Page A renders Component A which queries and displays contacts. We will call this query "contacts".

Query:

const gql = require("graphql-tag");
const { graphql } = require("react-apollo");

const { contactInfo } = require("../fragments");

const query = gql"
  query contacts {
    contacts {
      ...contactInfo
    }
  }
  ${ contactInfo }
";

const apolloQuery = graphql(query, { name: "contacts" })

module.exports = {
  query,
  apolloQuery
};

UpdateQueries:

graphql(ImportContacts, {
  props: ({ mutate }) => ({
    importContacts: (contacts) => mutate({
      variables: { contacts },
      updateQueries: {
        contacts: (prev, { mutationResult }) => ({
          contacts: [
            ...prev.contacts,
            ...mutationResult.data.importContacts.contacts
          ]
        }),
        accounts: (prev, { mutationResult }) => ({
          accounts: [
            ...prev.accounts,
            ...mutationResult.data.importContacts.accounts
          ]
        })
      }
    })
  })
});

Page B allows the user to import contacts. Page B does not render Component A, and so does not have the contacts query active.

Upon navigating back to Page A, the new contact does not exist in the list, but the old ones do (from the cache).

I figured this is where updateQueries would come in. However I have come to find that when Component A is unmounted, the query which received the data no longer exists. And so updateQueries is not called for the "contacts" query. (I confirmed this by adding the contacts query to Page B, and when the query was active, updateQueries was called as expected)

Is this the expected behaviour? If so, how should I go about handling this situation?

I'd rather not force a refetch every time, Component A is rendered. It is getting the cached results, so shouldn't there be a way to update those cached results even though the query is no longer active?

Version

  • apollo-client@0.6.0
  • react-apollo@0.8.1
@bradjabel bradjabel changed the title Update Queries that are no longer active, but the results are cached Update queries that are no longer active, but the results are cached Jan 15, 2017
@tmeasday
Copy link
Contributor

Hi @bradabelgit - this is a known issue with apollo-client I suppose. You can read a bit more about the rationale here: apollographql/apollo-client#1068 (comment)

I'll close this one in favor of apollographql/apollo-client#1068

@bradjabel
Copy link
Author

Thanks for the quick reply @tmeasday! Ah yes after following up on those links, I understand the problem.

Is there any workaround in the mean time? Or am I stuck refetching? If I do force a refetch, will the the current data in the cache be provided (for a faster UI), and then patch in any updates from the refetch?

@tmeasday
Copy link
Contributor

I guess it depends on what behaviour you want. Do you want to keep updating all queries that have ever been executed by the app (I guess this is what @helfer is trying to avoid)?

If so, you could look at a way to get an extra subscriber attached to every graphql container, so that they are never "freed".

Or do you want to treat some specific queries in a special way?

If you want to render the "stale" data quickly and then have the refetch happen, rather than passing forceFetch to the query, you could call refetch() in componentDidMount.

@bradjabel
Copy link
Author

bradjabel commented Jan 17, 2017

I really like the second option (calling refetch() in componentDidMount.

It would be nice if the data was there even before it is needed, especially since after most mutations I already know where that new data needs to be. However that doesn't seem to be possible at the moment unless the queries are never "freed". I could also look into prefetching the data.

Are there any major performance issues that could arise from holding on to all queries?

@tmeasday
Copy link
Contributor

Are there any major performance issues that could arise from holding on to all queries?

Depends what you mean I guess. In most applications this would be a CPU "leak" that would eventually kill the user's browser (think about keeping an infinitely growing list of queries up to date). So I'd say that's fairly major. However in some/most cases it might not happen that soon and not be a big deal.

Keep in mind that there's already a memory leak in that the query data stays there forever (cache expiration is on the todo list though), however my guess is that unless your app is really data heavy this is unlikely to hurt you very quickly. Maybe once the cache expiration is implemented it'd make sense to update all queries in cache?

@bradjabel
Copy link
Author

Yup that makes sense.

It would definitely be nice to have the ability to fine tune a cache expiration. In my case, I don't think I would want to clear the cache while a user is logged in at all. That being said, the amount of data I am dealing with is not all that crazy... yet.

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

2 participants