import { useCallback, useState } from "react"; import { RefreshControl, type RefreshControlProps } from "react-native"; type PullToRefreshProps = Omit & { onRefresh: () => Promise | 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 ( void handleRefresh()} /> ); }