-
Notifications
You must be signed in to change notification settings - Fork 13
Description
With react-query, let's say there's a books query with a staleTime of 10s:
await client.prefetchQuery({
queryKey: ['books'],
staleTime: 10_000,
queryFn: () =>
Promise.resolve([
{
id: '1',
name: 'Book 1',
comments: [...],
},
{
id: '2',
name: 'Book 2',
comments: [...],
},
]),
});After 10 seconds have passed, the query is considered stale. Let's say it's no longer on screen, so it should be refetched at the next mount.
A call to setNormalizedData due to a mutation, or manually like this:
normalizer.setNormalizedData({
id: '1',
name: 'Book 1 updated',
});will update the dataUpdatedAt property of every query that it touches. Book 1 in the books query will be updated and the books query will not be considered stale anymore and will not refetch at mount.
I think this behaviour is wrong, as even though we got some partial data back for Book 1, the rest of the data and the other books were not refreshed, so the books query should still be considered stale.
One use case I have is where I (as someone discussed in another issue) automatically call setNormalizedData when queries receive new data (like Apollo which I have used before does). But when I call queryClient.invalidateQueries() on a mutation (I still sometimes do even with Normy), all queries will first invalidate, but then setNormalizedData causes queries to immediately become valid again, if a previous query updates their data in some way.
Cause/fix
In the Normy internal function updateQueriesFromMutationData, react-query is called like this, which causes dataUpdatedAt to update:
queriesToUpdate.forEach(query => {
queryClient.setQueryData(
JSON.parse(query.queryKey) as QueryKey,
() => query.data,
)
})The latest dataUpdatedAt timestamp can instead be preserved like this:
queriesToUpdate.forEach(query => {
let queryKey = JSON.parse(query.queryKey) as QueryKey
queryClient.setQueryData(queryKey, () => query.data, {
updatedAt: queryClient.getQueryCache().find({ queryKey })?.state
.dataUpdatedAt,
})
})Relevant discussion: TanStack/query#4716 (comment)
I made this as an issue instead of a PR since it could be seen as a breaking change (even though the current behaviour is not documented), so I wanted to get some input on this first. Another option could be to add a parameter to setNormalizedData where the user can decide if the dataUpdatedAt timestamp should be touched or not.