Skip to content

Commit efebc9c

Browse files
authored
Merge pull request #37 from johanobergman/fix/query-state
Keep relevant query state in setNormalizedData
2 parents 5af0b5d + 2d517fe commit efebc9c

File tree

2 files changed

+71
-4
lines changed

2 files changed

+71
-4
lines changed

Diff for: packages/normy-react-query/src/create-query-normalizer.spec.ts

+52
Original file line numberDiff line numberDiff line change
@@ -521,4 +521,56 @@ describe('createQueryNormalizer', () => {
521521
},
522522
});
523523
});
524+
525+
it('keeps relevant query state on queries after setNormalizedData', async () => {
526+
const client = new QueryClient();
527+
const normalizer = createQueryNormalizer(client);
528+
normalizer.subscribe();
529+
530+
await client.prefetchQuery({
531+
queryKey: ['book'],
532+
queryFn: () =>
533+
Promise.resolve({
534+
id: '1',
535+
name: 'Name',
536+
}),
537+
});
538+
539+
// Set error state on the query.
540+
await client.prefetchQuery({
541+
queryKey: ['book'],
542+
queryFn: () => {
543+
throw new Error('Failed to fetch');
544+
},
545+
});
546+
547+
// Set isInvalidated on the query.
548+
await client.invalidateQueries({ queryKey: ['book'] });
549+
550+
const state1 = client.getQueryCache().find({ queryKey: ['book'] })?.state;
551+
552+
const dataUpdatedAt1 = state1?.dataUpdatedAt;
553+
const isInvalidated1 = state1?.isInvalidated;
554+
const error1 = state1?.error;
555+
const status1 = state1?.status;
556+
557+
await sleep(1);
558+
559+
normalizer.setNormalizedData({
560+
id: '1',
561+
name: 'Name updated',
562+
});
563+
564+
const state2 = client.getQueryCache().find({ queryKey: ['book'] })?.state;
565+
566+
const dataUpdatedAt2 = state2?.dataUpdatedAt;
567+
const isInvalidated2 = state2?.isInvalidated;
568+
const error2 = state2?.error;
569+
const status2 = state2?.status;
570+
571+
expect(dataUpdatedAt1).toEqual(dataUpdatedAt2);
572+
expect(isInvalidated1).toEqual(isInvalidated2);
573+
expect(error1).toEqual(error2);
574+
expect(status1).toEqual(status2);
575+
});
524576
});

Diff for: packages/normy-react-query/src/create-query-normalizer.ts

+19-4
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,25 @@ const updateQueriesFromMutationData = (
2424
const queriesToUpdate = normalizer.getQueriesToUpdate(mutationData);
2525

2626
queriesToUpdate.forEach(query => {
27-
queryClient.setQueryData(
28-
JSON.parse(query.queryKey) as QueryKey,
29-
() => query.data,
30-
);
27+
const queryKey = JSON.parse(query.queryKey) as QueryKey;
28+
const cachedQuery = queryClient.getQueryCache().find({ queryKey });
29+
30+
// react-query resets some state when setQueryData() is called.
31+
// We'll remember and reapply state that shouldn't
32+
// be reset when a query is updated via Normy.
33+
34+
// dataUpdatedAt and isInvalidated determine if a query is stale or not,
35+
// and we only want data updates from the network to change it.
36+
const dataUpdatedAt = cachedQuery?.state.dataUpdatedAt;
37+
const isInvalidated = cachedQuery?.state.isInvalidated;
38+
const error = cachedQuery?.state.error;
39+
const status = cachedQuery?.state.status;
40+
41+
queryClient.setQueryData(queryKey, () => query.data, {
42+
updatedAt: dataUpdatedAt,
43+
});
44+
45+
cachedQuery?.setState({ isInvalidated, error, status });
3146
});
3247
};
3348

0 commit comments

Comments
 (0)