Ivo
Ivo

Reputation: 2510

React/Apollo - Similar Queries in different Component?

I am looking for help regarding best practice using Apollo, React and Meteor.

I linked the Meteor.user() model to a Schema in Apollo and I can now access it thanks to a Query Component. I have a query that looks like this :

gql`
  query User {
    user {
      _id,
      email
    }
  }
`

and it does the job, with a resolver giving directly the email adress. However I need it in different places and for every component where I need it I am making another < Query > component with the same Query I copy paste from on file to another. It seems to me that I am loosing the all point if many of my components are querying again and again the same things. However I do not manage to find the solution to this "DRY" problem. There are not yet so many examples including the Query component from react apollo so if someone could help me with this it'd be much appreciated.

Upvotes: 2

Views: 2573

Answers (3)

Daniel Rearden
Daniel Rearden

Reputation: 84667

By default, the Apollo client uses a fetchPolicy of cache-first. That means if the result of the query is already in the cache, it will be fetched from there and no network request will be made. That allows you to use the same query across multiple Query components without having to worry about making the same request to your server over and over again.

You can specify the fetchPolicy for a particular Query component if you want to override this default behavior -- for example, maybe you want to always fetch new data from the server, in which case you would use network-only or maybe cache-and-network. See the docs for more details.

NOTE: A common "gotcha" is that the cache uses the id (or _id) field to normalize the cached results. That means your queries have to include the id field (or provide a custom implementation of dataIdFromObject) to see the expected behavior. See this page for additional details.

In terms of keeping things dry, it's common practice to store your queries in one or more separate modules and then import them as needed. So you could have a queries.js file like this:

import gql from 'graphql-tag'

export const USER_QUERY = gql`
  query User {
    user {
      _id,
      email
    }
  }
`

graphql-tag comes with a loader that lets you import queries directly from .graphql/.gql files if you're using Webpack. Check out the recipe here. There's also a babel plugin for doing effectively the same thing (checkout it out here). Any of these approaches should reduce the redundancy in your code.

EDIT: As pointed out in @camba1's answer, fragments can also be used to DRY up your queries:

query User {
  user {
    ...userFields
  }
}

fragment userFields on User {
  _id,
  email,
}

Upvotes: 3

camba1
camba1

Reputation: 1820

Another thing that may be useful to avoid having to copy paste query code all over the place is to use query fragments .

for example:

# Query that contains a fragment
query myQuery1($_key: ID!) {
  myQuery1(_key: $_key) {
    field1,
    ...myFragmentFields
    }
  }

# Fragment to be used in queries
fragment myFragmentFields on myQueryType {
    _key,
    name,
    formula,
    type
  }

Here is the documentation:

Upvotes: 2

xadm
xadm

Reputation: 8418

You can use cache-only or cache-first policy in query.

Docs

Upvotes: 0

Related Questions