Apollo Query Patterns with React & Redux


#1

So, let’s say I have two components: a NavBar with some accounts related buttons and a body component. I have a query that fetches some user data, and I’d like both components to have access to this data.

If I connect both of them using ‘connect’, the query runs twice. I’d prefer that it run once. I can connect their parent, and use mapStateToProps as I’d do with pure redux, but I can’t make heads or tails out of how I’m supposed to use the ‘apollo’ key in the state object.

How do I get the result of a query run on a parent object out of my state object? Or, if this is totally wrongheaded, is there a clear pattern to follow here?


#2

I would do something like

Parent Container -> connect queries that matter to all components
Navbar component -> user data via props
Body component -> user data via props

Lets say nav and body have their own query needs, connect those individually.


#3

The body route is a react-router component… forgot to mention that.


#4

Ideally, it wouldn’t be necessary to do anything to have Apollo Client handle this properly.

Did you check if it’s actually making two requests to the server? If the data is already in the store, the query will only once, unless you pass forceFetch.

The only thing is, if you ask for the same query twice at the same time (before the first instance returns), the client doesn’t yet have the data in the store so it will send it twice.

We could implement a feature to keep track of queries currently in flight, and make it so that requesting the same query or an overlapping one doesn’t send a redundant request.

I think we should document this approach as well, so that you can easily get the data for whatever query you want at any time, without going through Apollo Client. This is what Apollo Client already does internally, so it’s just a matter of exporting readQueryFromStore.


#5

@sashko
I do believe it’s fetching twice, as I’m logging the fetch on the server side. It seems likely that what you suggested - that they’re both firing off near simultaneously, neither finishing before the other - is happening.

All this is good to know!

readQueryFromStore sounds like the answer, to my immediate question.


#6

Here’s the code ApolloClient actually uses to read from the store and call the watchQuery observable: https://github.com/apollostack/apollo-client/blob/2ba9b95d1c9a83373ee6dcc0d17206bde6ab061c/src/QueryManager.ts#L189-L199

Maybe what we want is an option to watchQuery that never fetches data, and simply returns whatever happened to be in the store? And then later we can implement the in-flight query diffing if we feel really fancy. What do you think?


#7

Yea, I agree that having an option to force certain queries to only use data from the local store would be good. In-flight diffing would be good also, but if we have enough control over what we’re doing with our queries, the number of circumstances where we really need it should be pretty small.


#8

Can you file a feature request on Apollo client?