Reputation: 123
My apollo/client - useQuery is loading twice which is normal based on normal flow but when I have my network tab on devtools open and noticed weird stuff.
I have 2 cancelled request I don't know why.
My code is identical to apollo client docs
function Dogs({ onDogSelected }) {
const { loading, error, data } = useQuery(GET_DOGS);
if (loading) return 'Loading...';
if (error) return `Error! ${error.message}`;
return (
<select name="dog" onChange={onDogSelected}>
{data.dogs.map(dog => (
<option key={dog.id} value={dog.breed}>
{dog.breed}
</option>
))}
</select>
);
}
Anyone encountered this before?
Upvotes: 2
Views: 2282
Reputation: 1582
Most probably your code in _app.js
or wherever you instantiate the apolloClient
is ran multiple times (at re-render), trashing the old client and creating a new one, and the current apollo calls (attached to the old instance) get cancelled then re-run once the newly created apolloClient
is passed to the ApolloProvider
.
The solution for this would be to make the apolloClient
immutable and return the same instance unless the re-instantiation is necessary.
In my case, we had it set up like this:
_app.tsx:
const App = (props) => {
const apolloClient = useApollo({ language, location });
return (
<ApolloProvider client={apolloClient}>
{...}
</ApolloProvider>
);
}
apollo-client.ts
WRONG WAY:
export default function useApollo(config) {
return useMemo(() => createApolloClient(config), [config]);
}
GOOD WAY:
export default function useApollo() {
return useMemo(() => createApolloClient(config), [config.language, config.location]);
}
Notice how useMemo doesn't do the job because it's comparing objects (references) which are always different.
This is only one thing to watch out for but there are many other reasons your apolloClient
can get re-instantiated.
Upvotes: 2