React Native Assignment– 5

APIs, Auth, Caching & Offline

Basic Questions

  1. Create a service file (api/client.ts|js) with a base fetch/Axios instance pointing to a mock REST API and a 10s timeout.
  2. Build a ProductsScreen that fetches /products on mount and renders a list (name + price).
  3. Show loading, error, and empty states while requesting /products.
  4. Add an Authorization header (Bearer <token>) to all requests using an interceptor or wrapper function.
  5. Read a token from AsyncStorage and attach it to request headers; update the header when the token changes.
  6. Implement a pull-to-refresh on ProductsScreen that re-fetches data.
  7. Add a “Submit Feedback” form (name, email, message) and POST it to /feedback; show a success toast.
  8. Handle 2xx POST success by clearing the form and disabling the submit button during the request.
  9. Display server validation errors (4xx) under the appropriate input fields.
  10. Simulate a 5xx error (mock or intercept) and show a retry button that re-sends the last request.
  11. Implement paginated GET for /products?page=X&limit=20 with next/prev controls.
  12. Switch to infinite scroll: load the next page when the user reaches 80% of the list.
  13. Normalize API response objects to a local shape (e.g., snake_case → camelCase) before storing in state.
  14. Add a keyExtractor and stable renderItem to the list to avoid re-renders.
  15. Store fetched products in component state and memoize derived totals with useMemo.
  16. Add a top-level network status banner that shows when the app is offline.
  17. Log all requests and responses (method, URL, status, duration) to the console during development.
  18. Implement a global error boundary component for unexpected runtime errors in API screens.
  19. Add a cancel token/AbortController to cancel an in-flight request on unmount.
  20. Create a small useApi(url, params) hook that returns { data, loading, error, refetch }.

Intermediate Questions

  1. Install @react-native-async-storage/async-storage; write saveToken(token) and getToken() helpers and verify persistence across restarts.
  2. Cache /products responses in AsyncStorage and render the cached list immediately on app start (stale-while-revalidate).
  3. Add a cache version key; when schema changes, invalidate old cache and refetch.
  4. Implement etag/last-modified caching (mock headers) and send conditional requests; skip updates if 304 Not Modified.
  5. Add react-query (or @tanstack/react-query): wrap the app with QueryClientProvider and fetch /products using useQuery.
  6. Configure react-query caching: staleTime, cacheTime, and retry with exponential backoff; visualize with Devtools.
  7. Create useMutateFeedback() with react-query; on success, optimistically update a local feedback list and rollback on error.
  8. Create a paginated react-query (useInfiniteQuery) for /products with getNextPageParam.
  9. Persist the react-query cache to AsyncStorage (using persistQueryClient) and prove data survives app restarts.
  10. Add a rate limiter: queue requests to max 5 per second; throttle load-more calls.
  11. Centralize status-code handling: map 401 → force logout, 403 → show “forbidden”, 429 → backoff & retry after Retry-After.
  12. Add a request ID header and correlate it with server logs (print it in the UI).
  13. Create a products search input that debounces requests (300ms) and cancels stale queries.
  14. Implement file upload (feedback screenshot) via multipart/form-data and show progress (%).
  15. Add a toast/alert system for success and error messages; ensure no duplicate toasts on rapid retries.
  16. Build a ProductsDetailsScreen that fetches /products/:id and prefetches adjacent IDs when visible.
  17. Implement a 404 handler: navigate to a friendly “Not Found” screen for missing products.
  18. Write a transformResponse function that validates fields (id/name/price) and drops malformed entries.
  19. Use a selector to compute totals from normalized entities and confirm re-computation is memoized.
  20. Add a background refresh (AppState/Focus effect): refetch products when app returns to foreground.

Advanced Questions

  1. Build an offline-first task app (/tasks): list tasks from cache on launch, queue create/update/delete mutations when offline, and sync when online.
  2. Implement conflict resolution: if a remote task changed since local edit, present a merge UI (keep local/remote or combine) and resolve.
  3. Add per-entity dirty flags and a local syncQueue persisted in AsyncStorage; flush the queue with exponential backoff when network is available.
  4. Create a delta-sync endpoint mock: fetch only tasks changed since a lastSyncAt timestamp; store lastSyncAt and update after successful sync.
  5. Add background sync using react-native-background-fetch (or Headless JS on Android): schedule periodic sync and log runs.
  6. Implement image attachment uploads for tasks with offline support: store files temporarily, retry uploads, and reconcile URLs on success.
  7. Instrument your API layer with performance metrics (request duration, cache hit rate, retry count) and render a diagnostics panel.
  8. Add end-to-end encryption at rest for cached sensitive data (e.g., encrypt AsyncStorage with a key) and rotate the key on logout.
  9. Build a settings screen to configure cache sizes, stale times, retry/backoff policy, and a button to purge cache + sync queue.
  10. Final Hands-on Project:
    • Products: REST list + details with authentication headers, pagination (infinite scroll), retries, and caching (react-query + AsyncStorage persistence)
    • Feedback: form submission with optimistic update, file upload, and robust error handling (2xx/4xx/5xx)
    • Tasks (offline-first): local store, queued mutations, conflict resolution UI, delta-sync, background sync
    • Diagnostics: network status banner, logs, metrics panel, and settings to tune cache/backoff
    • Prove resilience: kill app mid-sync, toggle airplane mode, and demonstrate consistent state after recovery