Guide React Native 2026 : Développer des Applications Production et Questions d'Entretien

Guide complet pour développer des applications React Native prêtes pour la production en 2026 avec la Nouvelle Architecture, Expo SDK 56 et Hermes V1.

Guide React Native 2026 : Développer des Applications Production et Questions d'Entretien

Le développement d'applications React Native en 2026 repose sur la Nouvelle Architecture, Expo SDK 56 et des outils de production qui ont considérablement mûri au cours de l'année écoulée. Ce guide couvre le flux de travail pratique pour créer des applications en production et aborde les questions d'entretien courantes qui distinguent les développeurs React Native expérimentés.

Stack Production 2026

Le stack recommandé pour la production : Expo SDK 56 avec EAS Build, React Native 0.85+, moteur Hermes V1 et Nouvelle Architecture activée par défaut. Les temps de compilation ont diminué de 16% sur iOS et 60% sur Android par rapport au SDK 55.

Configurer un Projet React Native Prêt pour la Production

Démarrer un nouveau projet React Native en 2026 implique de choisir entre Expo (recommandé) et React Native bare. Expo a évolué d'un wrapper convivial pour débutants vers la recommandation officielle de l'équipe React Native pour la plupart des applications en production.

bash
# Créer un nouveau projet Expo avec SDK 56
npx create-expo-app@latest my-production-app
cd my-production-app

# Vérifier que la Nouvelle Architecture est activée (défaut depuis RN 0.76)
npx expo config --type introspect | grep newArchEnabled

La Nouvelle Architecture, qui inclut Fabric, TurboModules et JSI, élimine le pont JSON asynchrone qui causait des goulots d'étranglement de performance dans les applications complexes. JavaScript peut désormais appeler les modules natifs de manière synchrone, supprimant toute une catégorie de bugs de timing.

app.json - Configuration de productiontypescript
{
  "expo": {
    "name": "MyProductionApp",
    "slug": "my-production-app",
    "version": "1.0.0",
    "newArchEnabled": true, // Défaut dans SDK 56
    "android": {
      "package": "com.company.myproductionapp",
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#ffffff"
      }
    },
    "ios": {
      "bundleIdentifier": "com.company.myproductionapp",
      "supportsTablet": true
    },
    "plugins": [
      "expo-router"
    ]
  }
}

Expo Router est devenu le standard pour la navigation, apportant un routage basé sur les fichiers similaire à Next.js. La structure du répertoire /app correspond directement aux routes.

Moteur Hermes V1 et Performance JavaScript

Hermes V1 est livré comme moteur JavaScript par défaut dans React Native 0.84, remplaçant à la fois JavaScriptCore et l'ancien Hermes. Le nouveau compilateur et la machine virtuelle offrent une exécution du bytecode plus rapide, une empreinte mémoire réduite et une meilleure distribution des pauses de garbage collection.

typescript
// Surveillance des performances avec Hermes V1
// HermesInternal est disponible globalement lors de l'exécution sur Hermes
declare global {
  var HermesInternal: {
    getRuntimeProperties: () => Record<string, unknown>;
    enableSamplingProfiler: () => void;
    disableSamplingProfiler: () => string;
  } | undefined;
}

export function checkHermesStatus(): boolean {
  const isHermes = typeof HermesInternal === 'object' && HermesInternal !== null;

  if (isHermes && __DEV__) {
    const props = HermesInternal.getRuntimeProperties();
    console.log('Hermes version:', props['OSS Release Version']);
    console.log('Bytecode version:', props['Bytecode Version']);
  }

  return isHermes;
}

Hermes V1 précompile JavaScript en bytecode pendant le processus de build. Cela élimine l'analyse JavaScript à l'exécution, qui représente une partie significative du temps de démarrage de l'application. Les builds de production voient un Time to Interactive 10-30% plus rapide par rapport à JSC.

Compiler avec EAS Build et Compilation Optimisée

EAS Build gère les builds de production dans le cloud avec mise en cache, signature et distribution. Le SDK 56 a introduit des XCFrameworks pré-compilés pour les modules Expo sur iOS et un plugin compilateur Kotlin pour Android qui élimine la réflexion à l'exécution.

eas.json - Configuration de build productiontypescript
{
  "cli": {
    "version": ">= 15.0.0"
  },
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "ios": {
        "simulator": true
      }
    },
    "preview": {
      "distribution": "internal",
      "ios": {
        "resourceClass": "m-medium"
      },
      "android": {
        "buildType": "apk"
      }
    },
    "production": {
      "ios": {
        "resourceClass": "m-large"
      },
      "android": {
        "buildType": "app-bundle"
      },
      "env": {
        "EXPO_USE_PRECOMPILED_MODULES": "1"
      }
    }
  },
  "submit": {
    "production": {}
  }
}

Compiler l'application de production :

bash
# Build pour iOS App Store
eas build --platform ios --profile production

# Build pour Google Play
eas build --platform android --profile production

# Soumettre aux stores après le build
eas submit --platform all

La fonctionnalité d'en-têtes précompilés pour Android (usePrecompiledHeaders dans expo-build-properties) a réduit les temps de compilation CMake de 17 minutes à 6 minutes selon les benchmarks d'Expo.

Prêt à réussir tes entretiens React Native ?

Entraîne-toi avec nos simulateurs interactifs, fiches express et tests techniques.

Gestion d'État et Patterns de Récupération de Données

Les applications React Native en production combinent généralement TanStack Query pour l'état serveur avec Zustand ou Jotai pour l'état client. Cette séparation maintient la base de code prévisible et évite la complexité de Redux pour la plupart des cas d'utilisation.

hooks/useProducts.tstypescript
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '@/lib/api';
import type { Product } from '@/types';

// Factory de clés de requête pour une gestion du cache type-safe
export const productKeys = {
  all: ['products'] as const,
  lists: () => [...productKeys.all, 'list'] as const,
  list: (filters: ProductFilters) => [...productKeys.lists(), filters] as const,
  details: () => [...productKeys.all, 'detail'] as const,
  detail: (id: string) => [...productKeys.details(), id] as const,
};

export function useProducts(filters: ProductFilters) {
  return useQuery({
    queryKey: productKeys.list(filters),
    queryFn: () => api.products.list(filters),
    staleTime: 5 * 60 * 1000, // 5 minutes
    gcTime: 30 * 60 * 1000,   // 30 minutes (anciennement cacheTime)
  });
}

export function useCreateProduct() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (data: CreateProductInput) => api.products.create(data),
    onSuccess: () => {
      // Invalider les requêtes de liste pour refetch
      queryClient.invalidateQueries({ queryKey: productKeys.lists() });
    },
  });
}

Pour les fonctionnalités offline-first, combiner TanStack Query avec WatermelonDB ou le support SQLite intégré via expo-sqlite :

lib/offline-sync.tstypescript
import * as SQLite from 'expo-sqlite';
import NetInfo from '@react-native-community/netinfo';

const db = SQLite.openDatabaseSync('app.db');

export async function initializeOfflineStorage() {
  await db.execAsync(`
    CREATE TABLE IF NOT EXISTS pending_mutations (
      id TEXT PRIMARY KEY,
      type TEXT NOT NULL,
      payload TEXT NOT NULL,
      created_at INTEGER NOT NULL
    );
  `);
}

export async function queueMutation(type: string, payload: object) {
  const id = crypto.randomUUID();
  await db.runAsync(
    'INSERT INTO pending_mutations (id, type, payload, created_at) VALUES (?, ?, ?, ?)',
    [id, type, JSON.stringify(payload), Date.now()]
  );
}

export async function syncPendingMutations() {
  const state = await NetInfo.fetch();
  if (!state.isConnected) return;

  const pending = await db.getAllAsync<PendingMutation>(
    'SELECT * FROM pending_mutations ORDER BY created_at ASC'
  );

  for (const mutation of pending) {
    try {
      await processMutation(mutation);
      await db.runAsync('DELETE FROM pending_mutations WHERE id = ?', [mutation.id]);
    } catch (error) {
      console.error('Sync failed for mutation:', mutation.id);
      break; // Arrêter au premier échec pour maintenir l'ordre
    }
  }
}

Système d'Animation avec React Native Reanimated 4

React Native 0.85 a introduit un nouveau backend d'animation qui s'aligne avec la Nouvelle Architecture. Reanimated 4 en tire pleinement parti, exécutant les animations sur le thread UI sans traverser le pont JS.

components/AnimatedCard.tsxtypescript
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withSpring,
  withTiming,
  interpolate,
  Extrapolation,
} from 'react-native-reanimated';
import { Gesture, GestureDetector } from 'react-native-gesture-handler';

const SWIPE_THRESHOLD = 120;

export function SwipeableCard({ onSwipe, children }: SwipeableCardProps) {
  const translateX = useSharedValue(0);
  const opacity = useSharedValue(1);

  const panGesture = Gesture.Pan()
    .onUpdate((event) => {
      translateX.value = event.translationX;
    })
    .onEnd((event) => {
      if (Math.abs(event.translationX) > SWIPE_THRESHOLD) {
        const direction = event.translationX > 0 ? 'right' : 'left';
        translateX.value = withTiming(
          direction === 'right' ? 500 : -500,
          { duration: 200 }
        );
        opacity.value = withTiming(0, { duration: 200 }, () => {
          onSwipe(direction);
        });
      } else {
        translateX.value = withSpring(0, {
          damping: 15,
          stiffness: 150,
        });
      }
    });

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [
      { translateX: translateX.value },
      {
        rotate: `${interpolate(
          translateX.value,
          [-200, 0, 200],
          [-15, 0, 15],
          Extrapolation.CLAMP
        )}deg`,
      },
    ],
    opacity: opacity.value,
  }));

  return (
    <GestureDetector gesture={panGesture}>
      <Animated.View style={animatedStyle}>
        {children}
      </Animated.View>
    </GestureDetector>
  );
}

La directive worklet (implicite dans Reanimated 4 pour les fonctions passées à useAnimatedStyle) garantit que la logique d'animation s'exécute sur le thread UI. Cela permet d'atteindre un taux de rafraîchissement constant de 120Hz sur les appareils compatibles.

Questions d'Entretien pour Développeurs React Native

Les entretiens techniques pour les postes React Native en 2026 se concentrent fortement sur la Nouvelle Architecture, l'optimisation des performances et le déploiement en production. Explorez davantage de questions d'entretien React Native pour pratiquer des sujets spécifiques.

Qu'est-ce qui a changé avec la Nouvelle Architecture et pourquoi est-ce important ?

La Nouvelle Architecture a remplacé le pont JSON asynchrone par JSI (JavaScript Interface), permettant une communication synchrone entre JavaScript et le code natif. Trois composants forment le cœur :

  1. JSI : Une couche C++ qui permet à JavaScript de détenir des références vers des objets natifs et d'appeler leurs méthodes directement
  2. Fabric : Le nouveau système de rendu qui supporte les mesures de layout synchrones et le rendu concurrent
  3. TurboModules : Des modules natifs qui se chargent paresseusement et communiquent via JSI au lieu du pont

L'impact pratique : la contention du thread UI a diminué de 10-30% dans les applications typiques. Les applications avec une utilisation intensive de modules natifs voient jusqu'à 3x d'amélioration dans les performances d'appels inter-threads car le surcoût de sérialisation est éliminé.

En quoi Hermes V1 diffère-t-il de JavaScriptCore ?

Hermes V1 précompile JavaScript en bytecode au moment du build, éliminant l'étape d'analyse à l'exécution. Différences clés :

  • Temps de démarrage : Hermes saute l'analyse, réduisant le Time to Interactive de 10-30%
  • Mémoire : Utilisation mémoire de base plus faible grâce à la représentation optimisée du bytecode
  • Débogage : Hermes utilise le Chrome DevTools Protocol nativement, tandis que JSC nécessitait un adaptateur personnalisé
  • Garbage collection : Hermes utilise un GC générationnel avec des temps de pause plus courts

Le compromis : Hermes avait historiquement une vitesse d'exécution de pointe plus lente pour le code intensif en calcul, bien que V1 ait considérablement réduit cet écart.

Expliquez la différence entre useCallback, useMemo et React.memo dans React Native

Ces trois outils sont des outils de mémoïsation, mais ils servent des objectifs différents :

typescript
// useCallback : mémoïse une référence de fonction
const handlePress = useCallback(() => {
  navigation.navigate('Detail', { id: item.id });
}, [item.id, navigation]);

// useMemo : mémoïse une valeur calculée
const sortedItems = useMemo(() => {
  return items.slice().sort((a, b) => a.price - b.price);
}, [items]);

// React.memo : mémoïse la sortie de rendu d'un composant
const ProductCard = React.memo(function ProductCard({ product, onPress }: Props) {
  return (
    <Pressable onPress={onPress}>
      <Text>{product.name}</Text>
    </Pressable>
  );
});

Dans React Native, React.memo est particulièrement important pour les éléments de liste rendus par FlatList. Sans lui, chaque élément se re-rend quand l'état parent change, causant des pertes de frames pendant le défilement.

Comment gérer le deep linking dans une application React Native en production ?

Le deep linking nécessite une configuration à plusieurs niveaux : schémas d'URL natifs, liens universels/app links, et le routeur JavaScript.

app.json - Configurer les schémas d'URLtypescript
{
  "expo": {
    "scheme": "myapp",
    "ios": {
      "associatedDomains": ["applinks:myapp.com"]
    },
    "android": {
      "intentFilters": [
        {
          "action": "VIEW",
          "autoVerify": true,
          "data": [
            {
              "scheme": "https",
              "host": "myapp.com",
              "pathPrefix": "/product"
            }
          ],
          "category": ["BROWSABLE", "DEFAULT"]
        }
      ]
    }
  }
}

Expo Router gère automatiquement l'analyse lorsque la structure du répertoire app correspond aux chemins URL. Pour une gestion personnalisée :

app/_layout.tsxtypescript
import { useURL } from 'expo-linking';
import { useEffect } from 'react';
import { router } from 'expo-router';

export default function RootLayout() {
  const url = useURL();

  useEffect(() => {
    if (url) {
      const parsed = parseDeepLink(url);
      if (parsed.requiresAuth && !isAuthenticated) {
        // Stocker la destination prévue, rediriger vers login
        router.replace('/login');
      }
    }
  }, [url]);

  return <Slot />;
}

Les liens universels (iOS) et App Links (Android) nécessitent une configuration côté serveur : un fichier apple-app-site-association et un fichier assetlinks.json respectivement, servis depuis le domaine racine.

Passe à la pratique !

Teste tes connaissances avec nos simulateurs d'entretien et tests techniques.

Points Clés pour le Développement React Native en 2026

  • La Nouvelle Architecture est obligatoire : l'ancien pont a été désactivé dans React Native 0.82, et 85% des packages npm supportent maintenant la nouvelle architecture
  • Expo SDK 56 avec EAS Build fournit le chemin le plus rapide vers la production, avec des modules pré-compilés réduisant les temps de build iOS de 16% et la compilation CMake Android de 60%
  • Hermes V1 est le moteur par défaut sans configuration nécessaire, offrant un démarrage 10-30% plus rapide comparé à JSC
  • TanStack Query plus une bibliothèque légère d'état client (Zustand/Jotai) couvre la plupart des besoins de gestion de données en production sans la complexité de Redux
  • Reanimated 4 avec le nouveau backend d'animation atteint des animations à 120Hz en s'exécutant entièrement sur le thread UI
  • La préparation aux entretiens devrait se concentrer sur les mécanismes JSI, le rendu Fabric, le profilage de performance avec Hermes, et le déploiement en production avec EAS
Défi du jour

Tu saurais repérer le bug en React Native ?

Un vrai bout de code, un bug caché, une tentative par jour. Sans compte pour essayer.

Anthony Fillion-Maillet

Écrit par

Anthony Fillion-Maillet

Fondateur de SharpSkill

Développeur fullstack depuis plus de 10 ans. Il dirige SharpSkill et répond de tout ce qui y est publié.

Mis à jour le 14 septembre 2026

Partager

Articles similaires