seodev
Développement Mobile

React Native + Expo : nos 7 patterns en production

Architecture, navigation, deep links, push et offline-first : 7 patterns React Native et Expo éprouvés en production pour des apps stables et rapides.

FT
Fathellah TAHIRI
9 fév. 20263 min

React Native avec Expo, c'est notre stack de référence pour livrer des apps iOS et Android à partir d'une seule base de code. À force de projets, certains choix se sont imposés et se retrouvent systématiquement dans notre base de code. Les 7 patterns ci-dessous reviennent sur chacun de nos projets en production.

À retenir
  • Expo Router par défaut : routing par fichiers, deep links et Universal Links gérés par la structure.
  • Offline-first avec MMKV + React Query : cache local rapide, resynchronisation automatique.
  • Error Boundaries branchées sur Sentry : aucune erreur silencieuse en production.
  • EAS Update pour les correctifs : livraison OTA en quelques minutes, sans review des stores.

1. Navigation : Expo Router par défaut#

Expo Router apporte le file-based routing à React Native. Même logique que Next.js : les devs web s'y retrouvent immédiatement.

app/
├── (tabs)/
│   ├── index.tsx     // Onglet Home
│   ├── profile.tsx   // Onglet Profil
│   └── _layout.tsx   // Tab bar config
├── modal.tsx         // Modale (full-screen)
└── _layout.tsx       // Root layout (providers)
// app/product/[id].tsx
import { useLocalSearchParams } from 'expo-router'
 
export default function ProductScreen() {
  const { id } = useLocalSearchParams<{ id: string }>()
  // Accessible via myapp://product/123
  // ET via https://monsite.fr/product/123 (Universal Links)
}

3. Push notifications avec Expo Notifications#

La partie technique ci-dessous ne suffit pas : le timing de la demande de permission fait tout le taux d'opt-in. On a détaillé les règles de notifications depuis iOS 17.

import * as Notifications from 'expo-notifications'
import * as Device from 'expo-device'
 
async function registerForPushNotifications() {
  if (!Device.isDevice) return null
 
  const { status } = await Notifications.requestPermissionsAsync()
  if (status !== 'granted') return null
 
  const token = await Notifications.getExpoPushTokenAsync({
    projectId: Constants.expoConfig?.extra?.eas?.projectId,
  })
 
  return token.data
}

4. Offline-first avec MMKV + React Query#

import { MMKV } from 'react-native-mmkv'
import { QueryClient } from '@tanstack/react-query'
import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister'
 
const storage = new MMKV()
 
const persister = createSyncStoragePersister({
  storage: {
    getItem: (key) => storage.getString(key) ?? null,
    setItem: (key, value) => storage.set(key, value),
    removeItem: (key) => storage.delete(key),
  },
})

5. Performance : FlatList optimisée#

<FlatList
  data={items}
  keyExtractor={(item) => item.id}
  renderItem={({ item }) => <ItemCard item={item} />}
  // Ces 3 props sont critiques pour les listes longues
  removeClippedSubviews
  maxToRenderPerBatch={10}
  windowSize={10}
  // Evite les re-renders inutiles
  getItemLayout={(_, index) => ({
    length: ITEM_HEIGHT,
    offset: ITEM_HEIGHT * index,
    index,
  })}
/>

6. Gestion des erreurs avec Error Boundaries#

import * as Sentry from '@sentry/react-native'
 
export function AppErrorBoundary({ children }: { children: React.ReactNode }) {
  return (
    <Sentry.ErrorBoundary
      fallback={({ error, resetError }) => (
        <View style={styles.container}>
          <Text>Une erreur est survenue</Text>
          <Button title='Réessayer' onPress={resetError} />
        </View>
      )}
    >
      {children}
    </Sentry.ErrorBoundary>
  )
}

7. OTA updates avec EAS Update#

# Déploiement sans passer par l'App Store
eas update --channel production --message "Fix crash login"

Nos apps sont configurées pour checker les updates au démarrage. Les correctifs critiques arrivent chez les utilisateurs en moins de 10 minutes, sans attendre la review Apple.

Ce qu'on évite systématiquement#

  • expo-av pour la vidéo (préférer react-native-video)
  • Nested navigators trop profonds (max 3 niveaux)
  • useState pour l'état global (Zustand ou Jotai)
  • AsyncStorage (trop lent, MMKV est bien plus rapide)

Tous ces patterns s'écrivent en TypeScript strict, sans exception. Si vous vous demandez encore si React Native est le bon choix pour votre projet, on a posé notre raisonnement complet, et le détail de l'offre est sur la page application mobile.

Questions fréquentes

Pourquoi utiliser Expo Router plutôt que React Navigation seul ?

Expo Router apporte le routing par fichiers à React Native, sur le même modèle que Next.js : les développeurs web s'y retrouvent immédiatement, et les deep links comme les Universal Links sont gérés par la structure des fichiers elle-même.

Comment faire fonctionner une app React Native hors ligne ?

Le duo MMKV + React Query avec un persister couvre la majorité des besoins : les données sont mises en cache localement et resynchronisées au retour du réseau. MMKV est nettement plus rapide qu'AsyncStorage pour ce rôle.

Qu'est-ce qu'une mise à jour OTA avec EAS Update ?

Une mise à jour over-the-air livre le code JavaScript directement aux utilisateurs sans repasser par la validation des stores. Les correctifs non natifs arrivent en quelques minutes au lieu de quelques jours.

Quelles erreurs éviter sur une app React Native ?

Les plus coûteuses : AsyncStorage pour le stockage critique (MMKV est bien plus rapide), useState pour l'état global (préférer Zustand ou Jotai), et des navigateurs imbriqués trop profonds qui rendent la navigation imprévisible.

#react-native#expo#mobile#patterns
Partager cet article
FT
Fathellah TAHIRI
Fondateur seodev

Fondateur de seodev, l'agence dev et SEO. On y conçoit des sites, des SaaS et des apps solides, avec le référencement pensé dans le code dès le départ : visibles sur Google au lancement et conçus pour convertir. On écrit ici ce qu'on déploie en production.

Discuter de votre projet

Ce qu'on applique vraiment, par email

Nos méthodes de terrain en dev web, mobile, SaaS et SEO, pas de théorie recopiée. Un email quand on publie, jamais de spam.

Un projet en tête ?

On en parle gratuitement et on vous dit ce qui est faisable, dans quel délai et à quel prix.

Obtenir mon devis gratuit →
  • Réponse sous 24h
  • Sans engagement
  • Prix fixe sur le devis
Développement Mobile

Développer une application mobile : le guide

Le guide complet pour développer une application mobile : coût, délais, iOS ou Android, étapes du projet et choix technologiques, de l'idée aux stores.

Fathellah TAHIRI3 min
Développement Mobile

Combien coûte une application mobile ?

Combien coûte une application mobile ? Les vraies fourchettes de prix, ce qui les fait varier, et ce qu'on livre vraiment à partir de 12 900 € HT.

Fathellah TAHIRI5 min
Développement Mobile

iOS et Android : pourquoi on choisit React Native

Une seule base de code pour iOS et Android. On explique pourquoi on choisit React Native, ce qu'il fait très bien, ses vraies limites, et quand aller en natif.

Fathellah TAHIRI4 min
Retour au blog