Skip to content

Commit 873e7de

Browse files
avocadowastakentrojanowski
authored andcommitted
feat(useQuery): implement skip (#42)
1 parent 7e0eea9 commit 873e7de

File tree

2 files changed

+162
-2
lines changed

2 files changed

+162
-2
lines changed

src/__tests__/useQuery-test.tsx

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,3 +608,147 @@ it("shouldn't make obsolete renders in suspense mode", async () => {
608608

609609
expect(TasksWrapperWithProfiler).toHaveCommittedTimes(1);
610610
});
611+
612+
it('skips query in suspense mode', async () => {
613+
const client = createMockClient();
614+
const { container } = render(
615+
<TasksWrapper client={client} skip query={TASKS_QUERY} />
616+
);
617+
618+
expect(container).toMatchInlineSnapshot(`
619+
<div>
620+
Skipped loading of data
621+
</div>
622+
`);
623+
624+
await flushEffectsAndWait();
625+
626+
expect(container).toMatchInlineSnapshot(`
627+
<div>
628+
Skipped loading of data
629+
</div>
630+
`);
631+
});
632+
633+
it('skips query in non-suspense mode', async () => {
634+
const client = createMockClient();
635+
const { container } = render(
636+
<TasksWrapper client={client} skip suspend={false} query={TASKS_QUERY} />
637+
);
638+
639+
expect(container).toMatchInlineSnapshot(`
640+
<div>
641+
Skipped loading of data
642+
</div>
643+
`);
644+
645+
await flushEffectsAndWait();
646+
647+
expect(container).toMatchInlineSnapshot(`
648+
<div>
649+
Skipped loading of data
650+
</div>
651+
`);
652+
});
653+
654+
it('starts skipped query in suspense mode', async () => {
655+
const client = createMockClient();
656+
const { rerender, container } = render(
657+
<TasksWrapper client={client} skip query={TASKS_QUERY} />
658+
);
659+
660+
expect(container).toMatchInlineSnapshot(`
661+
<div>
662+
Skipped loading of data
663+
</div>
664+
`);
665+
666+
await flushEffectsAndWait();
667+
668+
expect(container).toMatchInlineSnapshot(`
669+
<div>
670+
Skipped loading of data
671+
</div>
672+
`);
673+
674+
rerender(<TasksWrapper client={client} skip={false} query={TASKS_QUERY} />);
675+
676+
expect(container).toMatchInlineSnapshot(`
677+
<div>
678+
679+
Loading
680+
</div>
681+
`);
682+
683+
await flushEffectsAndWait();
684+
685+
expect(container).toMatchInlineSnapshot(`
686+
<div>
687+
<ul>
688+
<li>
689+
Learn GraphQL
690+
</li>
691+
<li>
692+
Learn React
693+
</li>
694+
<li>
695+
Learn Apollo
696+
</li>
697+
</ul>
698+
</div>
699+
`);
700+
});
701+
702+
it('starts skipped query in non-suspense mode', async () => {
703+
const client = createMockClient();
704+
const { rerender, container } = render(
705+
<TasksWrapper client={client} skip suspend={false} query={TASKS_QUERY} />
706+
);
707+
708+
expect(container).toMatchInlineSnapshot(`
709+
<div>
710+
Skipped loading of data
711+
</div>
712+
`);
713+
714+
await flushEffectsAndWait();
715+
716+
expect(container).toMatchInlineSnapshot(`
717+
<div>
718+
Skipped loading of data
719+
</div>
720+
`);
721+
722+
rerender(
723+
<TasksWrapper
724+
client={client}
725+
skip={false}
726+
suspend={false}
727+
query={TASKS_QUERY}
728+
/>
729+
);
730+
731+
expect(container).toMatchInlineSnapshot(`
732+
<div>
733+
Loading without suspense
734+
</div>
735+
`);
736+
737+
await flushEffectsAndWait();
738+
739+
expect(container).toMatchInlineSnapshot(`
740+
<div>
741+
<ul>
742+
<li>
743+
Learn GraphQL
744+
</li>
745+
<li>
746+
Learn React
747+
</li>
748+
<li>
749+
Learn Apollo
750+
</li>
751+
</ul>
752+
</div>
753+
`);
754+
});

src/useQuery.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export interface QueryHookOptions<TVariables>
3232
notifyOnNetworkStatusChange?: boolean;
3333
pollInterval?: number;
3434
// custom options of `useQuery` hook
35+
skip?: boolean;
3536
suspend?: boolean;
3637
}
3738

@@ -51,6 +52,7 @@ export function useQuery<TData = any, TVariables = OperationVariables>(
5152
query: DocumentNode,
5253
{
5354
// Hook options
55+
skip = false,
5456
suspend = true,
5557

5658
// Watch options
@@ -115,11 +117,15 @@ export function useQuery<TData = any, TVariables = OperationVariables>(
115117
partial: result.partial,
116118
};
117119
},
118-
[responseId, observableQuery]
120+
[skip, responseId, observableQuery]
119121
);
120122

121123
useEffect(
122124
() => {
125+
if (skip) {
126+
return;
127+
}
128+
123129
const invalidateCurrentResult = () => setResponseId(x => x + 1);
124130
const subscription = observableQuery.subscribe(
125131
invalidateCurrentResult,
@@ -132,7 +138,7 @@ export function useQuery<TData = any, TVariables = OperationVariables>(
132138
subscription.unsubscribe();
133139
};
134140
},
135-
[observableQuery]
141+
[skip, observableQuery]
136142
);
137143

138144
ensureSupportedFetchPolicy(suspend, fetchPolicy);
@@ -145,6 +151,16 @@ export function useQuery<TData = any, TVariables = OperationVariables>(
145151
updateQuery: observableQuery.updateQuery.bind(observableQuery),
146152
};
147153

154+
if (skip) {
155+
// Taken from https://github.com/apollographql/react-apollo/blob/5cb63b3625ce5e4a3d3e4ba132eaec2a38ef5d90/src/Query.tsx#L376-L381
156+
return {
157+
...helpers,
158+
data: undefined,
159+
error: undefined,
160+
loading: false,
161+
};
162+
}
163+
148164
if (suspend && currentResult.partial) {
149165
// throw a promise - use the react suspense to wait until the data is
150166
// available

0 commit comments

Comments
 (0)