React Native Flow

← Retour au blog

April 2, 2026·10 min read

Maps: static previews vs live MapView

A static map image in a list cell is cheap, cacheable, and doesn’t need gestures. A full map belongs on a detail screen where the user can pan. Mixing them wrong drains battery and API quotas. Match the widget to the user’s task: glance vs explore.

Quotas and keys

Static Maps still bill per request. Cache URLs or images when markers don’t change every second.

Separate keys for dev with referrer restrictions when platforms allow.

UX

Don’t make users pinch inside a scroll view unless you enjoy support tickets. Disable scroll chaining or use a full-screen map.

Show permission rationale before location prompts.

Fallbacks

When maps fail, show address text and open maps app via deep link. Airplane mode happens.

Test on devices without Google Play Services if you ship Android worldwide.

Pick static vs interactive in one sentence

If the user only needs to confirm “this is roughly where it is,” ship a static image or thumbnail. If they need to explore, reroute, or see live location, use MapView (and pay the battery and permission cost).

Never stack multiple live maps in a list—your users and your bill will notice.

Choosing static previews versus interactive maps

Static map images excel in feeds: predictable cost, no gesture conflicts, easy caching, and no location permission until detail screens. Interactive `MapView` shines when users must explore, measure distance, or select precise pins—accept higher battery, GPU, and complexity costs. Mixed misuse—embedding interactive maps inside small list cells—drains devices and frustrates users who cannot distinguish scroll gestures from map pans. Decide per screen based on user tasks: glance versus navigate. For ride-sharing or delivery, interactivity is essential; for showing a restaurant neighborhood, static may suffice with a ‘open in maps’ affordance. Cost-control static usage too—thumbnail-sized still bills per request if uncached. Use server-side image generation or signed URLs with TTLs when possible. For offline, static cached images degrade more gracefully than tile servers. Always provide textual addresses as fallback—maps fail in tunnels and airplane mode.

API keys, quotas, and abuse prevention

Separate development and production keys; restrict keys by bundle id and referrer where platforms allow. Monitor dashboards for anomalous spikes—could be bugs, bots, or scraping. Rate-limit client requests and backoff—bursting markers can trigger throttling. For user-generated locations, validate coordinates and sanitize inputs before sending to geocoding APIs. Log errors with enough detail to debug map tile failures without exposing secrets. When quotas approach limits, alert before users see blank maps. For compliance, document map usage in privacy labels—location and imagery may be considered personal data depending on precision.

Gestures, layout, and scroll conflicts

Nested scrollables with maps require explicit height or `nestedScrollEnabled` patterns per platform docs—test on OEM devices with aggressive touch handling. Full-screen map screens often work better than embedded maps in scroll views. For bottom sheets over maps, watch z-index and touch interception. Dark mode and dynamic type should not obscure map controls—verify contrast. Accessibility: provide textual distance and ETA for screen reader users when maps are decorative; interactive map exploration may need alternative list directions. Test with poor GPS—indoor defaults and last-known-good locations should degrade politely.

Shipping checklist for map features

Keys restricted, quotas monitored, static versus interactive choice documented, permissions rationale shown, offline fallbacks tested, performance profiled on low-end Android, accessibility alternatives provided, and legal review for location data complete. After launch, monitor crash clusters related to map SDKs—native crashes bypass JS error boundaries. Keep SDKs updated—map vendors patch rendering and security bugs frequently.

Shipping and reliability habits (1)

Type-safe navigation pays off when routes multiply. Keep param lists near navigators, validate external URLs, and avoid serializing non-JSON-safe values through params. Renaming routes is a cross-cutting change—update analytics, push payloads, and E2E selectors in the same release train.

FlatList performance is configuration as much as code. Stable keys, reasonable `windowSize`, and memoized rows beat switching to a different list primitive blindly. Nested virtualized lists are a last resort—redesign first. Profile with production-like data volumes; dev placeholders lie.

Platform differences worth rehearsing (2)

Expo SDK upgrades are integration projects: `expo doctor`, aligned community packages, regenerated native projects, and device smoke tests for camera, push, and IAP. Freeze unrelated native refactors during the upgrade window and keep rollback paths hot. Document surprises for the next upgrade while memory is fresh.

Hermes versus JSC is not a lifestyle choice—profile your app. Hermes usually wins on startup; some libraries still assume JSC quirks. Engine toggles are not substitutes for fixing quadratic renders in your own code. Upgrade notes matter: Intl support and debugging tooling evolve.

Security, privacy, and data handling (3)

Design tokens and semantic colors make dark mode and rebrands feasible. Mixing three styling systems doubles migration cost—pick a primary approach and draw boundaries. Runtime CSS-in-JS can cost frame time on hot screens—profile before adopting wholesale.

ScrollView versus FlatList is a data-volume question. Small static content belongs in ScrollView; long feeds belong in virtualized lists. Nested scrollables need explicit height contracts—redesign beats fighting physics. Document intentional choices so future refactors do not ‘optimize’ blindly.

Performance and measurement discipline (4)

Shipping React Native features is less about any single API and more about the system around it: typed boundaries, predictable navigation, and telemetry that tells you what broke in production. Prefer boring, explicit modules over clever metaprogramming that the next hire cannot grep. When platform vendors change behavior in point releases, your defense is automated smoke tests on real devices and a short internal changelog of native assumptions you rely on.

Performance work should start with measurement, not instinct. Watch JS thread versus UI thread separately; they bottleneck differently. Lists, images, and animations dominate most regressions—optimize those before micro-optimizing pure functions. Hermes, JSC, and bridge internals evolve; re-profile after every major upgrade instead of trusting last year’s numbers. Battery and thermal throttling on mid devices reveal issues flagship phones hide.

Team process and long-term maintenance (5)

Native modules are product decisions disguised as engineering tasks. You inherit Xcode and Gradle upgrades, store review scrutiny, and security obligations. Prefer maintained Expo modules and config plugins before writing JNI or Swift glue from scratch. When you must go native, budget pairing time with platform specialists and write runbooks for on-call—crashes in native code bypass many JS safeguards.

Deep links are a cross-team system: marketing URLs, hosted association files, entitlements, router params, and analytics query preservation. Debug with structured logging of raw URLs (scrub secrets) and reproduce cold-start races with auth hydration. Staging and production should be obviously separated—accidentally opening prod from a QA link erodes trust and pollutes data.

Shipping and reliability habits (6)

WebViews are untrusted browsers inside your app. Validate `postMessage` payloads, lock navigation to expected hosts, and prefer system-browser auth flows when OAuth security demands it. Third-party JavaScript can change without your deploy—treat XSS in web as bridge compromise risk. Clear storage on logout and rate-limit message handlers.

E2E tests should protect revenue paths, not every permutation. Stable selectors (`testID`) beat text that marketing rewrites weekly. Flake management is a feature: quarantine, fix root causes, and keep smoke suites green on CI devices. Five reliable tests beat fifty flaky ones that everyone ignores.

Platform differences worth rehearsing (7)

Splash screens and launch gates should reflect honest readiness: fonts, theme, session, critical remote config—not every SDK under the sun. Infinite splash is worse than a slightly longer branded hold. Match native and JS background colors to avoid flashes; respect reduced motion for animations.

JWT and session refresh flows need single-flight refresh, clear logout semantics, and secure storage for refresh tokens when appropriate. Parallel 401s should not stampede refresh endpoints. Clock skew and biometrics policies belong in explicit product decisions, not accidental implementation details.

Security, privacy, and data handling (8)

Reanimated and gesture libraries earn their place when profiling proves UI-thread work and your team can maintain native upgrades. Worklets have constraints—read errors carefully. Respect reduced motion and test Android timing differences—identical JS does not guarantee identical feel.

Analytics schema governance prevents warehouse disasters: version events, avoid high-cardinality strings, and align names across iOS, Android, and web. Consent gating must stop network calls, not just UI. Separate dev and prod projects to avoid polluting dashboards.

Performance and measurement discipline (9)

Metro cache issues masquerade as logic bugs. Establish a documented reset ladder: dev server restart, cache flags, Watchman, derived data, then dependency reinstalls. Compare platforms when only one breaks—native steps diverge. Keep CI caches deterministic with lockfiles and pinned toolchains.

Environment variables should be classified: public-by-design, sensitive-with-mitigations, or never-on-device. `EXPO_PUBLIC_` values are extractable—treat them that way. Align env handling across EAS profiles and local dev; fail fast when keys are missing instead of shipping undefined behavior.

Team process and long-term maintenance (10)

Security and privacy expectations move faster than roadmaps. Treat analytics, crash, and attribution SDKs as part of your threat model: initialize them deliberately, document data flows, and verify ‘off’ truly stops network calls. Client-side secrets are public secrets—anything shipped in an APK or IPA should be assumed extractable. Pair mobile changes with backend policies so authorization remains consistent across platforms.

Accessibility is compatibility. Labels, focus order, and dynamic type are not polish—they determine whether users can complete tasks at all. Test with VoiceOver and TalkBack on hardware; simulators miss focus bugs. When designs prioritize minimalism, negotiate text alternatives for icon-only controls. Accessibility regressions often follow navigation redesigns—add checklist items to those PRs specifically.

Shipping and reliability habits (11)

Analytics schema governance prevents warehouse disasters: version events, avoid high-cardinality strings, and align names across iOS, Android, and web. Consent gating must stop network calls, not just UI. Separate dev and prod projects to avoid polluting dashboards.

Testing onboarding changes with funnel metrics beats debating opinions. Segment by acquisition channel and platform; back behavior differs. Skip paths must be genuine—dark patterns may win short metrics and destroy brand trust. Localization length tests prevent clipped CTAs in verbose languages.

Platform differences worth rehearsing (12)

Helper modules concentrate glue code—storage, navigation, permissions—so screens stay readable. Split helpers by topic before files become merge-conflict magnets, and document each module’s contract. Good helpers answer ‘where do we save tokens?’ in one glance—not ‘ask Sarah.’

Shipping React Native features is less about any single API and more about the system around it: typed boundaries, predictable navigation, and telemetry that tells you what broke in production. Prefer boring, explicit modules over clever metaprogramming that the next hire cannot grep. When platform vendors change behavior in point releases, your defense is automated smoke tests on real devices and a short internal changelog of native assumptions you rely on.

Security, privacy, and data handling (13)

Deep links are a cross-team system: marketing URLs, hosted association files, entitlements, router params, and analytics query preservation. Debug with structured logging of raw URLs (scrub secrets) and reproduce cold-start races with auth hydration. Staging and production should be obviously separated—accidentally opening prod from a QA link erodes trust and pollutes data.

Push notifications walk a line between helpful and intrusive. Prime users with context, respect notification channels on Android, and measure opt-outs after campaigns—spikes mean copy or frequency problems. Payload design affects background behavior; test killed and locked-device states. Tokens belong server-side with rotation strategies; never treat the client as authoritative for subscription state.

Performance and measurement discipline (14)

Keyboard and form UX separate polished apps from ‘works on desktop simulators.’ Platform differences in soft input modes matter; test smallest phones and Android gesture navigation. Primary actions must remain reachable when the keyboard is visible—scroll containers and keyboard controllers exist because this problem is universal.

Type-safe navigation pays off when routes multiply. Keep param lists near navigators, validate external URLs, and avoid serializing non-JSON-safe values through params. Renaming routes is a cross-cutting change—update analytics, push payloads, and E2E selectors in the same release train.

Team process and long-term maintenance (15)

Hermes versus JSC is not a lifestyle choice—profile your app. Hermes usually wins on startup; some libraries still assume JSC quirks. Engine toggles are not substitutes for fixing quadratic renders in your own code. Upgrade notes matter: Intl support and debugging tooling evolve.

Reanimated and gesture libraries earn their place when profiling proves UI-thread work and your team can maintain native upgrades. Worklets have constraints—read errors carefully. Respect reduced motion and test Android timing differences—identical JS does not guarantee identical feel.

Sponsorisé

Promo rapide