35 lines
984 B
TypeScript
35 lines
984 B
TypeScript
import { useCallback, useState } from "react";
|
|
import { RefreshControl, type RefreshControlProps } from "react-native";
|
|
|
|
type PullToRefreshProps = Omit<RefreshControlProps, "onRefresh" | "refreshing"> & {
|
|
onRefresh: () => Promise<unknown> | unknown;
|
|
};
|
|
|
|
/**
|
|
* Keeps the native refresh indicator tied to an actual pull gesture.
|
|
* Query `isRefetching` also covers background polling and invalidations, which
|
|
* can repeatedly move an offscreen iOS scroll view when used as `refreshing`.
|
|
*/
|
|
export function PullToRefresh({ onRefresh, ...props }: PullToRefreshProps) {
|
|
const [refreshing, setRefreshing] = useState(false);
|
|
|
|
const handleRefresh = useCallback(async () => {
|
|
if (refreshing) return;
|
|
|
|
setRefreshing(true);
|
|
try {
|
|
await onRefresh();
|
|
} finally {
|
|
setRefreshing(false);
|
|
}
|
|
}, [onRefresh, refreshing]);
|
|
|
|
return (
|
|
<RefreshControl
|
|
{...props}
|
|
refreshing={refreshing}
|
|
onRefresh={() => void handleRefresh()}
|
|
/>
|
|
);
|
|
}
|