Weird query lifecycle transitions
See original GitHub issueHey there! I discovered your library yesterday and decided to give it a try because I think its caching mechanism is superior to what graphql-hooks (what I’m currently using) offers.
What I’m doing
To make migration easier, I’m creating the following hook:
import { useGraphQL } from 'graphql-react';
const fetchOptionsOverride = options => {
options.url = '/api/graphql';
};
const useQuery = (query, { variables } = {}) => {
const {
loading,
cacheValue: { data, fetchError, httpError, parseError, graphQLErrors } = {},
} = useGraphQL({
fetchOptionsOverride,
operation: {
variables,
query,
},
});
const error = fetchError || httpError || parseError || graphQLErrors;
console.log({ loading, error, data }); // <- Remember this call to console.log.
return {
loading,
error,
data,
};
};
export default useQuery;
What I expect
Later, in my component I expect to be able to use useQuery
like this:
const postQuery = /* GraphQL */ `...`;
const Post = ({ postId }) => {
const { loading, error, data } = useQuery(postQuery, {
variables: {
postId,
},
});
if (loading) {
return 'Loading...';
}
if (error) {
return 'Something went wrong.';
}
return (
<article>
<h1>{data.post.title}</h1>
<p>{data.post.content}</p>
</article>
);
};
What actually happens
Blows up when trying to access data.post.title
. I traced that down to the different values loading
, error
and data
have during the query lifecycle:
{ loading: false, error: undefined, data: undefined }
All three values are falsy at the beginning, thus provoking the issue I just mentioned with my component’s code.
{ loading: true, error: undefined, data: undefined }
loading
is set to true
when load()
is called inside useGraphQL
.
{ loading: false, error: undefined, data: undefined }
When that finishes, loading
returns to false
, but neither error
nor data
are set (problematic, if you ask me).
{ loading: false, error: undefined, data: {…} }
Finally, data
is populated with the result of the GraphQL query.
I would expect this sequence to be like this instead:
{ loading: true, error: undefined, data: undefined }
{ loading: false, error: undefined, data: {…} }
Am I doing something wrong in my useQuery
hook? Is this the expected behavior?
Issue Analytics
- State:
- Created 4 years ago
- Comments:9 (7 by maintainers)
Thanks for your quick reply.
Actually as you can see in this codesandbox example, that’s not the case: https://codesandbox.io/s/green-architecture-023dc Doing 2 following
setState
still will trigger 1 single render with bothsetState
applied at the same time (not one after the other).Anyway I will try to have a look at the source code of the
useGraphQL
see if I find something. Good luck with your new contract!Yeah, weird. Let me try to reproduce the issue in a codesandbox. If I’m doing something wrong I’ll probably find out then. I’ll keep you posted.