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

cache-only queries render 3 times #2441

Closed
rcacheira opened this issue Sep 30, 2018 · 4 comments
Closed

cache-only queries render 3 times #2441

rcacheira opened this issue Sep 30, 2018 · 4 comments

Comments

@rcacheira
Copy link

rcacheira commented Sep 30, 2018

'cache-only' queries render 3 times with loading===false and the same data.

I've detected this error on another big project using 'graphql' and 'compose', here I'm showing a little example using v2 queries.

Intended console outcome:

serverInfo data: true loading: false: 1
homes data: true loading: false: 1

Actual console outcome:

serverInfo data: true loading: false: 1
homes data: true loading: false: 1
serverInfo data: true loading: false: 2
serverInfo data: true loading: false: 3
homes data: true loading: false: 2
homes data: true loading: false: 3

How to reproduce the issue:

Index.tsx:

import React from 'react';
import { render } from 'react-dom';
import ApolloClient, { InMemoryCache } from 'apollo-boost';
import { persistCache } from 'apollo-cache-persist';

import App from './App';

const cache = new InMemoryCache();

persistCache({
  cache,
  storage: window.localStorage,
}).then(() => {
  const client = new ApolloClient({ uri: "http://localhost:4000", cache });
  render(<App client={client} />, document.getElementById('root'));
});

App.tsx:

import React from 'react';
import { hot } from 'react-hot-loader';
import { Hello } from './Hello';
import { ApolloProvider } from 'react-apollo';
import ApolloClient from 'apollo-boost';

export interface Props {
  client: ApolloClient<{}>;
}

class App extends React.Component<Props> {
  render() {
    return (
      <ApolloProvider client={this.props.client}>
        <Hello />
      </ApolloProvider>
    );
  }
}

export default hot(module)(App);

Hello.tsx:

import React from 'react';
import { Query } from 'react-apollo';
import gql from 'graphql-tag';

const ServerInfo = gql`
  query ServerInfo {
    serverInfo {
      announcement
    }
  }
`;

const Homes = gql`
  query Homes {
    homes {
      name
      address
    }
  }
`;

export const Hello = () => (
  <div className="Hello">
    <h1>In the future this will be the XPTO web app</h1>
    <Query query={ServerInfo} fetchPolicy={'cache-only'}>
      {({ loading, error, data }) => {
        console.count(`serverInfo data: ${!!data.serverInfo} loading: ${loading}`);
        if (loading && !data.serverInfo) return <p>Loading...</p>;
        if (error) return <p>Error :(</p>;
        return <h3>{`Server announcement: ${data.serverInfo.announcement}`}</h3>;
      }}
    </Query>
    <Query query={Homes} fetchPolicy={'cache-only'}>
      {({ loading, error, data }) => {
        console.count(`homes data: ${!!data.homes} loading: ${loading}`);
        if (loading && !data.homes) return <p>Loading...</p>;
        if (error) return <p>Error :(</p>;
        return (
          <React.Fragment>
            <h2>Home list from server:</h2>
            {data.homes.map(({ name, address }, index) => (
              <div key={index}>
                <p>{`${name} - ${address}`}</p>
              </div>
            ))}
          </React.Fragment>
        );
      }}
    </Query>
  </div>
);

Local Storage:

apollo-cache-persist:

{"$ROOT_QUERY.serverInfo":{"announcement":"Please keep away! This server belongs to XPTO.","__typename":"ServerInfo"},"ROOT_QUERY":{"serverInfo":{"type":"id","generated":true,"id":"$ROOT_QUERY.serverInfo","typename":"ServerInfo"},"homes":[{"type":"id","generated":true,"id":"ROOT_QUERY.homes.0","typename":"Home"},{"type":"id","generated":true,"id":"ROOT_QUERY.homes.1","typename":"Home"}]},"ROOT_QUERY.homes.0":{"name":"Test1","address":"Venda do Pinheiro","__typename":"Home"},"ROOT_QUERY.homes.1":{"name":"Test2","address":"Lisboa","__typename":"Home"}}}

Version

This versions is the ones I used on this tiny example. With the other big project I'm using older versions.

  • apollo-client@2.4.2
  • react-apollo@2.2.1
  • apollo-boost@0.1.16
  • apollo-cache@1.1.17
  • apollo-cache-inmemory@^1.3.0
  • apollo-cache-inmemory@^1.2.10 (not sure about wich one is used as I have the 2 on yarn.lock)
  • apollo-cache-persist@^0.1.1
@rcacheira rcacheira changed the title cache-only querie cache-only queries render 3 times Sep 30, 2018
@rcacheira
Copy link
Author

rcacheira commented Oct 1, 2018

Making some tests I've detected that using fetchPolicy: 'cache-first' instead of fetchPolicy: 'cache-only'have the expected behaviour.

@joelgetaction
Copy link

Hey @rcacheira - does cache-first ever actually grab the data from the cache? It seems like based on apollographql/apollo-client#3452 that caching is totally broken in ApolloClient at the moment ...

@msimulcik
Copy link

Having the same issue. Here is a reproduction in CodeSandbox: https://codesandbox.io/s/9on9n1pl6o

@hwillson
Copy link
Member

This should no longer be an issue with current day react-apollo (>= 2.5.6), but let us know. Thanks!

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

4 participants