Skip to content

Instantly share code, notes, and snippets.

@sibelius
Created February 3, 2020 20:08
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sibelius/452ae872de6ebf7098b72a20fdd0fd85 to your computer and use it in GitHub Desktop.
Save sibelius/452ae872de6ebf7098b72a20fdd0fd85 to your computer and use it in GitHub Desktop.
Recursive fetch all items of a graphql connection using relay refetch container
import { useState, useEffect } from 'react';
import { RelayRefetchProp } from 'react-relay';
const TOTAL_REFETCH_ITEMS = 1000;
type PageInfo = {
hasNextPage: boolean;
startCursor: string | null;
endCursor: string | null;
};
type Edge<T> = {
cursor: string;
node: T;
};
type Connection<T> = {
count: number;
totalCount: number;
endCursorOffset: number;
startCursorOffset: number;
pageInfo: PageInfo;
edges: Edge<T>[];
};
type RecursiveRefetch<T> = {
connection: Connection<T>;
relay: RelayRefetchProp;
totalRefetchItems?: number;
};
export const useRecursiveRefetch = <T extends object>({
connection,
relay,
totalRefetchItems = TOTAL_REFETCH_ITEMS,
}: RecursiveRefetch<T>) => {
const [isLoading, setIsLoading] = useState<boolean>(true);
const [isFetching, setIsFetching] = useState<boolean>(false);
const { pageInfo, edges } = connection;
const recursiveRefetch = () => {
if (!pageInfo.hasNextPage) {
setIsLoading(false);
setIsFetching(false);
return;
}
if (pageInfo.hasNextPage) {
setIsFetching(true);
const total = edges.length + totalRefetchItems;
const renderVariables = { first: total };
const refetchVariables = fragmentVariables => ({
...fragmentVariables,
first: totalRefetchItems,
after: pageInfo.endCursor,
});
relay.refetch(refetchVariables, renderVariables, () => {
setIsFetching(false);
});
}
};
useEffect(() => {
if (!isLoading) {
return;
}
if (!isFetching) {
recursiveRefetch();
}
}, [isFetching]);
return [isLoading];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment