Skip to content

Commit

Permalink
Stop delaying useQuery calls by a microtask
Browse files Browse the repository at this point in the history
After #8414, the
changes made in #6107
are unnneccessary, because all ObservableQuery callbacks will only be
fired in useEffect calls (hopefully). This changes the timings of some
of tests.
  • Loading branch information
brainkim committed Jul 31, 2021
1 parent 559d354 commit 21eab53
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 31 deletions.
33 changes: 11 additions & 22 deletions src/react/hooks/__tests__/useQuery.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,6 @@ describe('useQuery Hook', () => {
variables: { something }
},
result: { data: CAR_RESULT_DATA },
delay: 1000
}));

let renderCount = 0;
Expand Down Expand Up @@ -1103,7 +1102,7 @@ describe('useQuery Hook', () => {
expect(result.current.loading).toBe(false);
expect(result.current.networkStatus).toBe(NetworkStatus.ready);
expect(result.current.data).toEqual({ letters: ab });
result.current.fetchMore({
act(() => void result.current.fetchMore({
variables: { limit: 2 },
updateQuery: (prev, { fetchMoreResult }) => ({
letters: prev.letters.concat(fetchMoreResult.letters),
Expand Down Expand Up @@ -1144,14 +1143,13 @@ describe('useQuery Hook', () => {
expect(result.current.networkStatus).toBe(NetworkStatus.ready);
expect(result.current.data).toEqual({ letters: ab });

result.current.fetchMore({
act(() => void result.current.fetchMore({
variables: { limit: 2 },
updateQuery: (prev, { fetchMoreResult }) => ({
letters: prev.letters.concat(fetchMoreResult.letters),
}),
});
}));

await waitForNextUpdate();
expect(result.current.loading).toBe(true);
expect(result.current.networkStatus).toBe(NetworkStatus.fetchMore);
expect(result.current.data).toEqual({ letters: ab });
Expand Down Expand Up @@ -1232,9 +1230,7 @@ describe('useQuery Hook', () => {
expect(result.current.networkStatus).toBe(NetworkStatus.ready);
expect(result.current.data).toEqual({ letters: ab });

result.current.fetchMore({ variables: { limit: 2 } });

await waitForNextUpdate();
act(() => void result.current.fetchMore({ variables: { limit: 2 } }));
expect(result.current.loading).toBe(true);
expect(result.current.networkStatus).toBe(NetworkStatus.fetchMore);
expect(result.current.data).toEqual({ letters: ab });
Expand Down Expand Up @@ -1777,7 +1773,7 @@ describe('useQuery Hook', () => {
{
request: { query: mutation },
error: new Error('Oh no!'),
delay: 10,
delay: 500,
}
];

Expand Down Expand Up @@ -1833,13 +1829,15 @@ describe('useQuery Hook', () => {

act(() => void mutate());
// The mutation ran and is loading the result. The query stays at not
// loading as nothing has changed for the query.
// loading as nothing has changed for the query, but optimistic data is
// rendered.

expect(result.current.mutation[1].loading).toBe(true);
expect(result.current.query.loading).toBe(false);

expect(result.current.query.data).toEqual(allCarsData);
await waitForNextUpdate();
// There is a missing update here because mutation and query update in
// the same microtask loop.
// TODO: There is a missing update here because mutation and query update
// in the same microtask loop.
const previous = result.all[result.all.length - 2];
if (previous instanceof Error) {
throw previous;
Expand All @@ -1850,15 +1848,6 @@ describe('useQuery Hook', () => {
expect(previous.mutation[1].loading).toBe(true);
expect(previous.query.loading).toBe(false);

// The first part of the mutation has completed using the defined
// optimisticResponse data. This means that while the mutation stays in a
// loading state, it has made its optimistic data available to the query.
// New optimistic data doesn't trigger a query loading state.
expect(result.current.mutation[1].loading).toBe(true);
expect(result.current.query.loading).toBe(false);
expect(result.current.query.data).toEqual(allCarsData);

await waitForNextUpdate();
// The mutation has completely finished, leaving the query with access to
// the original cache data.
expect(result.current.mutation[1].loading).toBe(false);
Expand Down
12 changes: 3 additions & 9 deletions src/react/hooks/useQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -587,18 +587,12 @@ export function useQuery<TData = any, TVariables = OperationVariables>(
options: updatedOptions,
context,
onNewData() {
if (!queryData.ssrInitiated()) {
// When new data is received from the `QueryData` object, we want to
// force a re-render to make sure the new data is displayed. We can't
// force that re-render if we're already rendering however so to be
// safe we'll trigger the re-render in a microtask. In case the
// component gets unmounted before this callback fires, we re-check
// queryDataRef.current.isMounted before calling forceUpdate().
Promise.resolve().then(() => queryDataRef.current && queryDataRef.current.isMounted && forceUpdate());
} else {
if (queryData.ssrInitiated()) {
// If we're rendering on the server side we can force an update at
// any point.
forceUpdate();
} else if (queryDataRef.current && queryDataRef.current.isMounted) {
forceUpdate();
}
}
})
Expand Down

0 comments on commit 21eab53

Please sign in to comment.