React Native Assignment– 5
APIs, Auth, Caching & Offline
Basic Questions
- Create a service file (api/client.ts|js) with a base fetch/Axios instance pointing to a mock REST API and a 10s timeout.
- Build a ProductsScreen that fetches /products on mount and renders a list (name + price).
- Show loading, error, and empty states while requesting /products.
- Add an Authorization header (Bearer <token>) to all requests using an interceptor or wrapper function.
- Read a token from AsyncStorage and attach it to request headers; update the header when the token changes.
- Implement a pull-to-refresh on ProductsScreen that re-fetches data.
- Add a “Submit Feedback” form (name, email, message) and POST it to /feedback; show a success toast.
- Handle 2xx POST success by clearing the form and disabling the submit button during the request.
- Display server validation errors (4xx) under the appropriate input fields.
- Simulate a 5xx error (mock or intercept) and show a retry button that re-sends the last request.
- Implement paginated GET for /products?page=X&limit=20 with next/prev controls.
- Switch to infinite scroll: load the next page when the user reaches 80% of the list.
- Normalize API response objects to a local shape (e.g., snake_case → camelCase) before storing in state.
- Add a keyExtractor and stable renderItem to the list to avoid re-renders.
- Store fetched products in component state and memoize derived totals with useMemo.
- Add a top-level network status banner that shows when the app is offline.
- Log all requests and responses (method, URL, status, duration) to the console during development.
- Implement a global error boundary component for unexpected runtime errors in API screens.
- Add a cancel token/AbortController to cancel an in-flight request on unmount.
- Create a small useApi(url, params) hook that returns { data, loading, error, refetch }.
Intermediate Questions
- Install @react-native-async-storage/async-storage; write saveToken(token) and getToken() helpers and verify persistence across restarts.
- Cache /products responses in AsyncStorage and render the cached list immediately on app start (stale-while-revalidate).
- Add a cache version key; when schema changes, invalidate old cache and refetch.
- Implement etag/last-modified caching (mock headers) and send conditional requests; skip updates if 304 Not Modified.
- Add react-query (or @tanstack/react-query): wrap the app with QueryClientProvider and fetch /products using useQuery.
- Configure react-query caching: staleTime, cacheTime, and retry with exponential backoff; visualize with Devtools.
- Create useMutateFeedback() with react-query; on success, optimistically update a local feedback list and rollback on error.
- Create a paginated react-query (useInfiniteQuery) for /products with getNextPageParam.
- Persist the react-query cache to AsyncStorage (using persistQueryClient) and prove data survives app restarts.
- Add a rate limiter: queue requests to max 5 per second; throttle load-more calls.
- Centralize status-code handling: map 401 → force logout, 403 → show “forbidden”, 429 → backoff & retry after Retry-After.
- Add a request ID header and correlate it with server logs (print it in the UI).
- Create a products search input that debounces requests (300ms) and cancels stale queries.
- Implement file upload (feedback screenshot) via multipart/form-data and show progress (%).
- Add a toast/alert system for success and error messages; ensure no duplicate toasts on rapid retries.
- Build a ProductsDetailsScreen that fetches /products/:id and prefetches adjacent IDs when visible.
- Implement a 404 handler: navigate to a friendly “Not Found” screen for missing products.
- Write a transformResponse function that validates fields (id/name/price) and drops malformed entries.
- Use a selector to compute totals from normalized entities and confirm re-computation is memoized.
- Add a background refresh (AppState/Focus effect): refetch products when app returns to foreground.
Advanced Questions
- Build an offline-first task app (/tasks): list tasks from cache on launch, queue create/update/delete mutations when offline, and sync when online.
- Implement conflict resolution: if a remote task changed since local edit, present a merge UI (keep local/remote or combine) and resolve.
- Add per-entity dirty flags and a local syncQueue persisted in AsyncStorage; flush the queue with exponential backoff when network is available.
- Create a delta-sync endpoint mock: fetch only tasks changed since a lastSyncAt timestamp; store lastSyncAt and update after successful sync.
- Add background sync using react-native-background-fetch (or Headless JS on Android): schedule periodic sync and log runs.
- Implement image attachment uploads for tasks with offline support: store files temporarily, retry uploads, and reconcile URLs on success.
- Instrument your API layer with performance metrics (request duration, cache hit rate, retry count) and render a diagnostics panel.
- Add end-to-end encryption at rest for cached sensitive data (e.g., encrypt AsyncStorage with a key) and rotate the key on logout.
- Build a settings screen to configure cache sizes, stale times, retry/backoff policy, and a button to purge cache + sync queue.
- 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