Fix/apollo client spamming infinite requets on failure (#450)
* Remove abort controller by default from requests Apollo client is, for whatever reason, considering it a new hook call when passing an abort controller to be passed to the actual request. On request failures this then causes infinite requests due to it being a new hook call. * Move side effect into useEffect This was missed and started causing issues after the changes of 60429d9d98544e1e49a112aacf77bdbb831740ec. Due to the changes, the component did not re-render unnecessarily which caused the component not to re-render with the fetched data * Reset fetching initial pages state The state was never reset, thus, in case of an error, the initial pages fetch was never triggered again
This commit is contained in:
@@ -225,9 +225,11 @@ type CustomApolloOptions = {
|
|||||||
* which - I assume - results in apollo to handle this as a completely new hook call.
|
* which - I assume - results in apollo to handle this as a completely new hook call.
|
||||||
* Due to this, when e.g. calling "fetchMore", "loading" and "networkStatus" do not get updated when enabling "notifyOnNetworkStatusChange".
|
* Due to this, when e.g. calling "fetchMore", "loading" and "networkStatus" do not get updated when enabling "notifyOnNetworkStatusChange".
|
||||||
*
|
*
|
||||||
* By not passing an abort signal, the states get correctly updated, BUT it won't be possible to abort the request.
|
* It also causes apollo to spam requests in case of request failures on every rerender.
|
||||||
|
*
|
||||||
|
* Instead of adding the abort signal by default, it has to be added manually which will cause these stated issues (and potentially more?)
|
||||||
*/
|
*/
|
||||||
omitAbortSignal?: boolean;
|
addAbortSignal?: boolean;
|
||||||
};
|
};
|
||||||
type QueryOptions<Variables extends OperationVariables = OperationVariables, Data = any> = Partial<
|
type QueryOptions<Variables extends OperationVariables = OperationVariables, Data = any> = Partial<
|
||||||
ApolloQueryOptions<Variables, Data>
|
ApolloQueryOptions<Variables, Data>
|
||||||
@@ -251,7 +253,7 @@ type ApolloPaginatedMutationOptions<Data = any, Variables extends OperationVaria
|
|||||||
type SubscriptionHookOptions<Data = any, Variables extends OperationVariables = OperationVariables> = Partial<
|
type SubscriptionHookOptions<Data = any, Variables extends OperationVariables = OperationVariables> = Partial<
|
||||||
ApolloSubscriptionHookOptions<Data, Variables>
|
ApolloSubscriptionHookOptions<Data, Variables>
|
||||||
> &
|
> &
|
||||||
Omit<CustomApolloOptions, 'omitAbortSignal'> & { omitAbortSignal?: never };
|
Omit<CustomApolloOptions, 'addAbortSignal'> & { addAbortSignal?: never };
|
||||||
|
|
||||||
type AbortableRequest = { abortRequest: AbortController['abort'] };
|
type AbortableRequest = { abortRequest: AbortController['abort'] };
|
||||||
|
|
||||||
@@ -552,16 +554,21 @@ export class RequestManager {
|
|||||||
areFetchingInitialPages: boolean,
|
areFetchingInitialPages: boolean,
|
||||||
areInitialPagesFetched: boolean,
|
areInitialPagesFetched: boolean,
|
||||||
setRevalidationDone: (isDone: boolean) => void,
|
setRevalidationDone: (isDone: boolean) => void,
|
||||||
cacheInitialPagesKey: string,
|
cacheFetchingInitialPagesKey: string,
|
||||||
getVariablesFor: (page: number) => Variables,
|
getVariablesFor: (page: number) => Variables,
|
||||||
initialPages: number,
|
initialPages: number,
|
||||||
fetchPage: (page: number) => Promise<FetchResult<Data>>,
|
fetchPage: (page: number) => Promise<FetchResult<Data>>,
|
||||||
hasNextPage: (result: FetchResult<Data>) => boolean,
|
hasNextPage: (result: FetchResult<Data>) => boolean,
|
||||||
): void {
|
): void {
|
||||||
const shouldFetchInitialPages = !options?.skipRequest && !areFetchingInitialPages && !areInitialPagesFetched;
|
useEffect(() => {
|
||||||
if (shouldFetchInitialPages) {
|
const shouldFetchInitialPages =
|
||||||
|
!options?.skipRequest && !areFetchingInitialPages && !areInitialPagesFetched;
|
||||||
|
if (!shouldFetchInitialPages) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setRevalidationDone(true);
|
setRevalidationDone(true);
|
||||||
this.cache.cacheResponse(cacheInitialPagesKey, getVariablesFor(0), true);
|
this.cache.cacheResponse(cacheFetchingInitialPagesKey, getVariablesFor(0), true);
|
||||||
|
|
||||||
const loadInitialPages = async (initialPage: number) => {
|
const loadInitialPages = async (initialPage: number) => {
|
||||||
const areAllPagesFetched = initialPage > initialPages;
|
const areAllPagesFetched = initialPage > initialPages;
|
||||||
@@ -576,8 +583,10 @@ export class RequestManager {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
loadInitialPages(1);
|
loadInitialPages(1).finally(() =>
|
||||||
}
|
this.cache.cacheResponse(cacheFetchingInitialPagesKey, getVariablesFor(0), false),
|
||||||
|
);
|
||||||
|
}, [!options?.skipRequest, !areFetchingInitialPages, !areInitialPagesFetched]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private returnPaginatedMutationResult<Data = any, Variables extends OperationVariables = OperationVariables>(
|
private returnPaginatedMutationResult<Data = any, Variables extends OperationVariables = OperationVariables>(
|
||||||
@@ -722,7 +731,7 @@ export class RequestManager {
|
|||||||
context: {
|
context: {
|
||||||
...options?.context,
|
...options?.context,
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
signal: options?.omitAbortSignal ? undefined : signal,
|
signal: options?.addAbortSignal ? signal : undefined,
|
||||||
...options?.context?.fetchOptions,
|
...options?.context?.fetchOptions,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -738,7 +747,7 @@ export class RequestManager {
|
|||||||
context: {
|
context: {
|
||||||
...options?.context,
|
...options?.context,
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
signal: options?.omitAbortSignal ? undefined : signal,
|
signal: options?.addAbortSignal ? signal : undefined,
|
||||||
...options?.context?.fetchOptions,
|
...options?.context?.fetchOptions,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -754,7 +763,7 @@ export class RequestManager {
|
|||||||
context: {
|
context: {
|
||||||
...options?.context,
|
...options?.context,
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
signal: options?.omitAbortSignal ? undefined : signal,
|
signal: options?.addAbortSignal ? signal : undefined,
|
||||||
...options?.context?.fetchOptions,
|
...options?.context?.fetchOptions,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -770,7 +779,7 @@ export class RequestManager {
|
|||||||
context: {
|
context: {
|
||||||
...options?.context,
|
...options?.context,
|
||||||
fetchOptions: {
|
fetchOptions: {
|
||||||
signal: options?.omitAbortSignal ? undefined : signal,
|
signal: options?.addAbortSignal ? signal : undefined,
|
||||||
...options?.context?.fetchOptions,
|
...options?.context?.fetchOptions,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ const SourceSearchPreview = React.memo(
|
|||||||
const { id, displayName, lang } = source;
|
const { id, displayName, lang } = source;
|
||||||
const [, results] = requestManager.useSourceSearch(id, searchString ?? '', undefined, 1, {
|
const [, results] = requestManager.useSourceSearch(id, searchString ?? '', undefined, 1, {
|
||||||
skipRequest: !searchString,
|
skipRequest: !searchString,
|
||||||
|
addAbortSignal: true,
|
||||||
});
|
});
|
||||||
const { data: searchResult, isLoading, error, abortRequest } = results[0]!;
|
const { data: searchResult, isLoading, error, abortRequest } = results[0]!;
|
||||||
const mangas = searchResult?.fetchSourceManga.mangas ?? [];
|
const mangas = searchResult?.fetchSourceManga.mangas ?? [];
|
||||||
|
|||||||
@@ -108,7 +108,6 @@ export const Updates: React.FC = () => {
|
|||||||
} = requestManager.useGetRecentlyUpdatedChapters(undefined, {
|
} = requestManager.useGetRecentlyUpdatedChapters(undefined, {
|
||||||
fetchPolicy: 'cache-and-network',
|
fetchPolicy: 'cache-and-network',
|
||||||
notifyOnNetworkStatusChange: true,
|
notifyOnNetworkStatusChange: true,
|
||||||
omitAbortSignal: true,
|
|
||||||
});
|
});
|
||||||
const hasNextPage = !!chapterUpdateData?.chapters.pageInfo.hasNextPage;
|
const hasNextPage = !!chapterUpdateData?.chapters.pageInfo.hasNextPage;
|
||||||
const endCursor = chapterUpdateData?.chapters.pageInfo.endCursor;
|
const endCursor = chapterUpdateData?.chapters.pageInfo.endCursor;
|
||||||
|
|||||||
Reference in New Issue
Block a user