Skip to content

Commit

Permalink
Merge pull request #37 from johanobergman/fix/query-state
Browse files Browse the repository at this point in the history
Keep relevant query state in setNormalizedData
  • Loading branch information
klis87 authored Jan 11, 2025
2 parents 5af0b5d + 2d517fe commit efebc9c
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 4 deletions.
52 changes: 52 additions & 0 deletions packages/normy-react-query/src/create-query-normalizer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -521,4 +521,56 @@ describe('createQueryNormalizer', () => {
},
});
});

it('keeps relevant query state on queries after setNormalizedData', async () => {
const client = new QueryClient();
const normalizer = createQueryNormalizer(client);
normalizer.subscribe();

await client.prefetchQuery({
queryKey: ['book'],
queryFn: () =>
Promise.resolve({
id: '1',
name: 'Name',
}),
});

// Set error state on the query.
await client.prefetchQuery({
queryKey: ['book'],
queryFn: () => {
throw new Error('Failed to fetch');
},
});

// Set isInvalidated on the query.
await client.invalidateQueries({ queryKey: ['book'] });

const state1 = client.getQueryCache().find({ queryKey: ['book'] })?.state;

const dataUpdatedAt1 = state1?.dataUpdatedAt;
const isInvalidated1 = state1?.isInvalidated;
const error1 = state1?.error;
const status1 = state1?.status;

await sleep(1);

normalizer.setNormalizedData({
id: '1',
name: 'Name updated',
});

const state2 = client.getQueryCache().find({ queryKey: ['book'] })?.state;

const dataUpdatedAt2 = state2?.dataUpdatedAt;
const isInvalidated2 = state2?.isInvalidated;
const error2 = state2?.error;
const status2 = state2?.status;

expect(dataUpdatedAt1).toEqual(dataUpdatedAt2);
expect(isInvalidated1).toEqual(isInvalidated2);
expect(error1).toEqual(error2);
expect(status1).toEqual(status2);
});
});
23 changes: 19 additions & 4 deletions packages/normy-react-query/src/create-query-normalizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,25 @@ const updateQueriesFromMutationData = (
const queriesToUpdate = normalizer.getQueriesToUpdate(mutationData);

queriesToUpdate.forEach(query => {
queryClient.setQueryData(
JSON.parse(query.queryKey) as QueryKey,
() => query.data,
);
const queryKey = JSON.parse(query.queryKey) as QueryKey;
const cachedQuery = queryClient.getQueryCache().find({ queryKey });

// react-query resets some state when setQueryData() is called.
// We'll remember and reapply state that shouldn't
// be reset when a query is updated via Normy.

// dataUpdatedAt and isInvalidated determine if a query is stale or not,
// and we only want data updates from the network to change it.
const dataUpdatedAt = cachedQuery?.state.dataUpdatedAt;
const isInvalidated = cachedQuery?.state.isInvalidated;
const error = cachedQuery?.state.error;
const status = cachedQuery?.state.status;

queryClient.setQueryData(queryKey, () => query.data, {
updatedAt: dataUpdatedAt,
});

cachedQuery?.setState({ isInvalidated, error, status });
});
};

Expand Down

0 comments on commit efebc9c

Please sign in to comment.