React Native et GraphQL en 2026 : Apollo Client, Requêtes et Questions d'Entretien

Guide complet pour intégrer GraphQL et Apollo Client 4.0 dans une application React Native. Configuration, requêtes typées, mutations optimistes et questions techniques d'entretien.

React Native et GraphQL avec Apollo Client

GraphQL s'est imposé comme la couche API de référence pour les applications React Native nécessitant une récupération de données flexible et une utilisation réseau optimisée. Apollo Client 4.0, publié fin 2025, apporte une architecture allégée avec des bundles 20 à 30% plus légers et un support TypeScript amélioré spécifiquement conçu pour les environnements mobiles.

Changements clés d'Apollo Client 4.0

Apollo Client 4.0 découple les exports spécifiques à React vers @apollo/client/react, supporte React 19 Suspense et le React Compiler, et remplace le monolithique ApolloError par des classes d'erreurs spécifiques pour un débogage amélioré.

Configuration d'Apollo Client 4 dans React Native

Le processus d'installation reste simple. Apollo Client 4.0 fonctionne aussi bien avec Expo qu'avec les projets React Native bare.

bash
# Installation
npm install @apollo/client graphql

L'initialisation du client nécessite un HttpLink pour les requêtes réseau et un InMemoryCache pour la gestion d'état local.

src/apollo/client.tstypescript
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client';

const httpLink = new HttpLink({
  uri: 'https://api.example.com/graphql',
  // Enable text streaming for @defer and subscriptions
  fetchOptions: {
    reactNative: { textStreaming: true },
  },
});

export const apolloClient = new ApolloClient({
  link: httpLink,
  cache: new InMemoryCache({
    typePolicies: {
      Query: {
        fields: {
          // Merge paginated results
          products: {
            keyArgs: ['category'],
            merge(existing = [], incoming) {
              return [...existing, ...incoming];
            },
          },
        },
      },
    },
  }),
});

La configuration typePolicies gère la normalisation du cache pour les données paginées, une exigence courante dans les applications mobiles avec défilement infini.

Encapsulation de l'Application avec ApolloProvider

Le pattern provider connecte Apollo Client à l'arbre de composants React. Il se place au niveau racine, généralement dans App.tsx ou le layout Expo Router.

App.tsxtsx
import { ApolloProvider } from '@apollo/client/react';
import { apolloClient } from './src/apollo/client';
import { RootNavigator } from './src/navigation';

export default function App() {
  return (
    <ApolloProvider client={apolloClient}>
      <RootNavigator />
    </ApolloProvider>
  );
}

Apollo Client 4.0 importe les hooks React depuis @apollo/client/react plutôt que depuis le point d'entrée principal. Ce changement réduit la taille du bundle lorsque le client core s'exécute dans des contextes non-React.

Écriture de Requêtes GraphQL Typées

GraphQL Code Generator produit des types TypeScript à partir du schéma, éliminant les incompatibilités de types à l'exécution. Il s'installe avec le plugin client.

bash
# Install codegen tools
npm install -D @graphql-codegen/cli @graphql-codegen/client-preset

La configuration codegen pointe vers le schéma et spécifie les emplacements de sortie.

codegen.tstypescript
import type { CodegenConfig } from '@graphql-codegen/cli';

const config: CodegenConfig = {
  schema: 'https://api.example.com/graphql',
  documents: ['src/**/*.tsx', 'src/**/*.ts'],
  generates: {
    './src/gql/': {
      preset: 'client',
      config: {
        documentMode: 'string',
      },
    },
  },
};

export default config;

L'exécution de npx graphql-codegen génère des nœuds de document typés que le hook useQuery consomme.

Récupération de Données avec useQuery

Le hook useQuery gère les états de chargement, les erreurs et les mises à jour du cache. Apollo Client 4.0 introduit l'API dataState pour des transitions d'état plus prévisibles.

src/screens/ProductListScreen.tsxtsx
import { useQuery } from '@apollo/client/react';
import { graphql } from '../gql';
import { ActivityIndicator, FlatList, Text, View } from 'react-native';

const GET_PRODUCTS = graphql(`
  query GetProducts($category: String!, $limit: Int, $offset: Int) {
    products(category: $category, limit: $limit, offset: $offset) {
      id
      name
      price
      imageUrl
    }
  }
`);

export function ProductListScreen({ category }: { category: string }) {
  const { data, loading, error, fetchMore } = useQuery(GET_PRODUCTS, {
    variables: { category, limit: 20, offset: 0 },
    // Fetch from cache first, then network
    fetchPolicy: 'cache-and-network',
    // Keep previous data while fetching new
    notifyOnNetworkStatusChange: true,
  });

  if (error) {
    return <Text>Error: {error.message}</Text>;
  }

  const loadMore = () => {
    fetchMore({
      variables: { offset: data?.products.length ?? 0 },
    });
  };

  return (
    <FlatList
      data={data?.products ?? []}
      keyExtractor={(item) => item.id}
      renderItem={({ item }) => <ProductCard product={item} />}
      onEndReached={loadMore}
      onEndReachedThreshold={0.5}
      ListFooterComponent={loading ? <ActivityIndicator /> : null}
    />
  );
}

La politique de récupération cache-and-network affiche immédiatement les données en cache tout en rafraîchissant depuis le serveur. Ce pattern réduit la latence perçue sur les réseaux mobiles.

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

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

Mutations et Mises à Jour Optimistes

Les mutations modifient les données côté serveur et mettent à jour le cache local. Les réponses optimistes fournissent un retour instantané avant que le serveur ne confirme le changement.

src/hooks/useAddToCart.tstsx
import { useMutation } from '@apollo/client/react';
import { graphql } from '../gql';

const ADD_TO_CART = graphql(`
  mutation AddToCart($productId: ID!, $quantity: Int!) {
    addToCart(productId: $productId, quantity: $quantity) {
      id
      items {
        id
        product {
          id
          name
        }
        quantity
      }
      totalPrice
    }
  }
`);

export function useAddToCart() {
  const [addToCart, { loading }] = useMutation(ADD_TO_CART, {
    // Optimistic response for instant UI feedback
    optimisticResponse: ({ productId, quantity }) => ({
      addToCart: {
        __typename: 'Cart',
        id: 'current-cart',
        items: [],
        totalPrice: 0,
      },
    }),
    // Update cache after mutation
    update(cache, { data }) {
      if (!data?.addToCart) return;
      cache.modify({
        id: cache.identify({ __typename: 'Cart', id: 'current-cart' }),
        fields: {
          items: () => data.addToCart.items,
          totalPrice: () => data.addToCart.totalPrice,
        },
      });
    },
  });

  return { addToCart, loading };
}

La méthode cache.modify met à jour directement les champs en cache sans refaire une requête complète. Cette approche minimise les requêtes réseau sur les connexions cellulaires.

Gestion des Erreurs Réseau dans les Applications Mobiles

Apollo Client 4.0 remplace le générique ApolloError par des classes d'erreurs spécifiques. Les méthodes statiques .is() permettent une gestion d'erreurs typée.

src/components/ErrorBoundary.tsxtsx
import { NetworkError, GraphQLErrors } from '@apollo/client/errors';
import { Text, Button, View } from 'react-native';

interface Props {
  error: Error;
  onRetry: () => void;
}

export function QueryErrorHandler({ error, onRetry }: Props) {
  // Network failure (offline, timeout, DNS)
  if (NetworkError.is(error)) {
    return (
      <View>
        <Text>Connexion échouée. Vérifiez votre connexion internet.</Text>
        <Button title="Réessayer" onPress={onRetry} />
      </View>
    );
  }

  // GraphQL validation or resolver errors
  if (GraphQLErrors.is(error)) {
    const firstError = error.graphQLErrors[0];
    if (firstError?.extensions?.code === 'UNAUTHENTICATED') {
      return <Text>Session expirée. Veuillez vous reconnecter.</Text>;
    }
    return <Text>Requête échouée: {firstError?.message}</Text>;
  }

  return <Text>Une erreur est survenue</Text>;
}

Distinguer les erreurs réseau des erreurs GraphQL permet différentes stratégies de récupération : réessayer pour les échecs transitoires, rediriger pour les problèmes d'authentification.

Support Hors-ligne avec Persistance du Cache

Les applications mobiles nécessitent un accès hors-ligne aux données précédemment récupérées. La bibliothèque apollo3-cache-persist sérialise le cache vers AsyncStorage.

src/apollo/persistence.tstypescript
import AsyncStorage from '@react-native-async-storage/async-storage';
import { persistCache } from 'apollo3-cache-persist';
import { apolloClient } from './client';

export async function initializeCache() {
  await persistCache({
    cache: apolloClient.cache,
    storage: AsyncStorage,
    maxSize: 1024 * 1024 * 5, // 5 MB limit
    debounce: 1000, // Write at most once per second
  });
}

Appeler initializeCache avant le rendu de l'application restaure les données en cache depuis le disque. Les utilisateurs voient leur dernier contenu récupéré immédiatement, même sans accès réseau.

Mises à Jour en Temps Réel avec les Subscriptions GraphQL

Les subscriptions transmettent les événements serveur au client via WebSocket. Apollo Client 4.0 supporte le protocole plus récent graphql-ws.

src/apollo/client.tstypescript
import { split, HttpLink, ApolloClient, InMemoryCache } from '@apollo/client';
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
import { createClient } from 'graphql-ws';
import { getMainDefinition } from '@apollo/client/utilities';

const httpLink = new HttpLink({ uri: 'https://api.example.com/graphql' });

const wsLink = new GraphQLWsLink(
  createClient({
    url: 'wss://api.example.com/graphql',
    connectionParams: async () => ({
      authToken: await getStoredToken(),
    }),
  })
);

// Route subscriptions to WebSocket, others to HTTP
const splitLink = split(
  ({ query }) => {
    const definition = getMainDefinition(query);
    return (
      definition.kind === 'OperationDefinition' &&
      definition.operation === 'subscription'
    );
  },
  wsLink,
  httpLink
);

export const apolloClient = new ApolloClient({
  link: splitLink,
  cache: new InMemoryCache(),
});

La fonction split dirige les opérations vers le transport approprié en fonction du type d'opération.

Questions d'Entretien Courantes : React Native GraphQL

Les entretiens techniques sondent souvent la compréhension des compromis spécifiques à GraphQL sur mobile. Les questions suivantes apparaissent fréquemment dans les positions React Native.

Pourquoi choisir GraphQL plutôt que REST pour les applications mobiles ?

GraphQL réduit le sur-fetching en ne retournant que les champs demandés. Une seule requête remplace plusieurs endpoints REST, réduisant les allers-retours sur les connexions cellulaires à haute latence. Le schéma typé permet une validation à la compilation, détectant les incompatibilités API avant l'exécution.

Comment Apollo Client met-il en cache les données ?

Apollo normalise les réponses par __typename et id, stockant chaque entité une seule fois. Les requêtes référencent les objets normalisés par clé de cache. Cette déduplication économise de la mémoire et assure la cohérence : mettre à jour un produit dans une liste le met à jour partout.

Quelles politiques de récupération Apollo Client supporte-t-il ?

PolitiqueComportementCas d'utilisation
cache-firstRetourne le cache si disponible, sinon fetchPar défaut, minimise les requêtes
cache-and-networkRetourne le cache immédiatement, puis mise à jour réseauDonnées fraîches avec affichage instantané
network-onlyToujours fetch, mise à jour du cacheQuand les données périmées sont inacceptables
cache-onlyJamais de fetch, échec si non en cacheMode hors-ligne
no-cacheFetch sans mise en cacheDonnées sensibles

Comment fonctionnent les mises à jour optimistes ?

Le client prédit le résultat de la mutation et met à jour le cache avant que le serveur ne réponde. Si le serveur retourne un résultat différent, Apollo remplace les données optimistes par la réponse réelle. Si la mutation échoue, Apollo revient à l'état précédent.

Qu'est-ce qui cause un problème N+1 en GraphQL ?

Les resolvers imbriqués qui récupèrent individuellement les données liées créent des requêtes N+1. Demander une liste de 50 produits avec leurs catégories déclenche 1 requête produits plus 50 requêtes catégories. Le DataLoader côté serveur regroupe celles-ci en une seule requête.

Comment gérer les tokens d'authentification avec Apollo Client ?

L'approche recommandée utilise un Apollo Link pour attacher les tokens à chaque requête.

src/apollo/authLink.tstypescript
import { setContext } from '@apollo/client/link/context';
import { getStoredToken } from '../auth/storage';

export const authLink = setContext(async (_, { headers }) => {
  const token = await getStoredToken();
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : '',
    },
  };
});

Chaîner ce link avant le HttpLink dans la configuration du client.

Débogage GraphQL dans React Native

Apollo fournit plusieurs options de débogage pour le développement React Native. L'extension Apollo pour VS Code inclut des DevTools Client intégrés qui affichent le contenu du cache et l'historique des requêtes.

Pour un débogage autonome, Flipper s'intègre avec le plugin communautaire react-native-apollo-devtools. Ce plugin inspecte l'état du cache, surveille les requêtes en cours et rejoue les mutations.

L'inspection réseau via React Native Debugger nécessite l'activation de "Debug JS Remotely". L'onglet Network affiche alors les payloads GraphQL avec les corps de requête et de réponse.

Points Clés pour le Développement GraphQL Mobile

  • Apollo Client 4.0 réduit la taille du bundle de 20-30% grâce à un packaging ESM-first et des exports React découplés.
  • La politique de récupération cache-and-network équilibre affichage instantané et fraîcheur des données sur les connexions lentes.
  • Les mises à jour optimistes fournissent un retour immédiat ; cache.modify évite les refetch inutiles.
  • Les classes d'erreurs typées dans Apollo Client 4.0 permettent une gestion spécifique des échecs réseau versus les erreurs GraphQL.
  • La persistance du cache avec apollo3-cache-persist permet l'accès hors-ligne aux données précédemment récupérées.
  • Les subscriptions GraphQL nécessitent le protocole graphql-ws et une configuration split link.
  • Les questions d'entretien se concentrent sur les stratégies de cache, les politiques de récupération et les compromis spécifiques au mobile comme la prévention N+1.

Passe à la pratique !

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

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 20 août 2026

Tags

#react-native
#graphql
#apollo-client
#typescript
#mobile

Partager

Articles similaires