Build an offline-first React Native data-fetching hook and list component
Produces a typed useOfflineQuery hook with cache-first reads, optimistic revalidation, and retry-on-reconnect, plus a FlatList that renders loading, empty, error, stale, and offline states honestly.
You are a senior React Native engineer who builds offline-first data layers that survive bad networks. I need an offline-first data-fetching hook and the list component that consumes it. Spec: [DESCRIBE THE SCREEN AND DATA — e.g. 'a product catalog fetched from /api/products, shown in a 2-column grid, must work offline once loaded'] Target stack: - Framework: [Expo / React Native CLI] - Data layer: [TanStack Query / SWR / hand-rolled cache] - Persistence: [AsyncStorage / MMKV / none — in-memory only] - List: [FlatList / FlashList] Build two things: 1) A typed useOfflineQuery hook with: - Cache-first reads: return cached data instantly, then revalidate in the background. - Network-aware behavior using NetInfo: queue a refetch when connectivity returns; never crash offline. - Retry with exponential backoff on transient errors; stop retrying on 4xx. - Distinct status flags: isLoading, isFetching, isStale, isError, isOffline — each observable, no overloaded loading booleans. - A generic type signature so callers get typed data. 2) A DataList component that consumes the hook and renders every state honestly: - Loading skeleton on first load (not a spinner on an empty list). - Stale banner when showing cached data older than [N] minutes while refetching. - Empty state with a retry CTA when the result set is genuinely empty. - Error state with a retry button; offline state that clearly says so. - Accessibility: status changes are announced, list items have stable keys and labels. Requirements: - Pure; no global stores inside the hook. No deprecated APIs. Functional components and hooks only. - No silent failures: every error path surfaces to the UI. Output, in this exact order: 1. A 3-bullet design rationale (cache strategy, revalidation triggers, state model). 2. The full useOfflineQuery.ts file. 3. The full DataList.tsx file. 4. A usage example showing the hook and list wired to my endpoint. 5. A test checklist: offline toggle, stale-then-fresh transition, error-then-retry. Success signal: the output is good only if the hook exposes distinct loading, fetching, stale, offline, and error states, the list renders an honest UI for each, and the whole thing degrades gracefully with no network.
Use case
Use when your app must read remote data that keeps working on flaky networks and offline, with a list UI that shows every state honestly.
When to use this
For read-heavy screens (feeds, catalogs, inboxes) where stale data is acceptable and offline support is required. Not for real-time-only data or write-heavy flows.
Follow-up prompts
- Add mutations with optimistic updates and rollback on failure.
- Wire the cache to a persistent store (WatermelonDB / MMKV) for cold-start offline reads.
- Add pull-to-refresh and infinite-scroll pagination to the list component.
- Source
- promptfork seed
- License
- CC-BY-4.0
- Published
- 6/22/2026