`useQuery` refetches whenever there's a state change in the same component.
Closed this issue · 2 comments
I already discussed this on discord with @vicary. I just prepared some minimal reproductions to easily check the issue.
Summary
Whenever there's a useState
or any state changing variable within the same component where useQuery
is. If you check the network requests tab, and change the state (for instance, incrementing a counter), you'll see multiple requests are made on it.
function App() {
const [count, setCount] = useState(0);
const authors = useQuery()?.authors;
return (
<>
<h1>Look at Networks Tab</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
</div>
<>);
}
Reproductions:
- CodeSandbox - Uses AniList API
- Blankeos/grats-gqty - A React & GQTY + Grats & Hono.
Workaround
The current workaround for this is to always make a separate component for the useQuery
, and also make a separate component for useState
where state changes happen.
Also, instead of passing the authors
directly, I have to put it in an intermediary variable. I initially thought I had to useMemo
the intermediary variable, but no need.
Here's an example of the workaround: CodeSandbox
In short, the refetch behaviour is expected.
In Discord, we've discussed the usage of useEffect
, reducing unnecessary renders.
GQty has a few things to consider when you are ready to optimize refetches.
- Whether
refetchOnRender
is enabled inuseQuery
, and - The
cachePolicy
option inuseQuery
, and - The
maxAge
andstaleWhileRevalidate
option of the cache in your generated client.
You may want to start with increasing the maxAge
option, it would reduce the fetches. If you are used to other GraphQL clients, put Infinity
there and it will never refetch automatically.