Skip to content

Instantly share code, notes, and snippets.

@sibelius
Created February 27, 2019 15:47
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sibelius/22d2690dd1146a96ebeda47f9a664efd to your computer and use it in GitHub Desktop.
Save sibelius/22d2690dd1146a96ebeda47f9a664efd to your computer and use it in GitHub Desktop.
useRelayPagination to be used with React Native Flatlist
const {
isFetchingEnd,
isFetchingTop,
onRefresh,
onEndReached,
} = useRelayPagination(relay, users);
const isRefreshing = isFetchingEnd || isFetchingTop;
<FlatList
data={users.edges}
renderItem={renderRow}
onEndReached={onEndReached}
onRefresh={onRefresh}
refreshing={isRefreshing}
keyExtractor={item => item.node.id}
/>
import { useState } from 'react';
import { RelayRefetchProp } from 'react-relay';
type PageInfo = {
hasNextPage: boolean,
hasPreviousPage: boolean,
startCursor: string,
endCursor: string,
}
type Edge<T> = {
node: T,
cursor: string,
}
type Connection<T> = {
endCursorOffset: number,
startCursorOffset: number,
count: number,
totalCount: number,
pageInfo: PageInfo,
edges: Edge<T>[],
}
export const useRelayPagination = <T extends object>(relay: RelayRefetchProp, connection: Connection<T>) => {
const [isFetchingTop, setIsFetchingTop] = useState(false);
const [isFetchingEnd, setIsFetchingEnd] = useState(false);
const onRefresh = () => {
if (isFetchingTop) { return; }
setIsFetchingTop(true);
const refetchVariables = (fragmentVariables: object) => ({
...fragmentVariables,
});
relay.refetch(
refetchVariables,
null,
() => {
setIsFetchingTop(false);
setIsFetchingEnd(false);
},
{
force: true,
},
);
};
const onEndReached = () => {
if (isFetchingEnd) { return; }
if (!connection || !connection.pageInfo.hasNextPage) { return; }
setIsFetchingEnd(true);
const { endCursor } = connection.pageInfo;
const total = connection.edges.length + 10;
const refetchVariables = (fragmentVariables: object) => ({
...fragmentVariables,
first: 10,
cursor: endCursor,
});
const renderVariables = {
first: total,
};
relay.refetch(
refetchVariables,
renderVariables,
() => {
setIsFetchingEnd(false);
setIsFetchingTop(false);
},
{
force: false,
},
);
};
return {
isFetchingEnd,
isFetchingTop,
onRefresh,
onEndReached,
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment