React Native e GraphQL nel 2026: Apollo Client, Query e Domande da Colloquio

Integrazione di GraphQL con React Native utilizzando Apollo Client 4.0. Questo tutorial copre query, mutation, strategie di caching e domande comuni sui colloqui per lo sviluppo mobile GraphQL.

Architettura codice integrazione React Native e GraphQL con Apollo Client

GraphQL è diventato il livello API preferito per le applicazioni React Native che richiedono un recupero dati flessibile e un utilizzo efficiente della rete. Apollo Client 4.0, rilasciato alla fine del 2025, porta un'architettura più snella con bundle ridotti del 20-30% e un supporto TypeScript migliorato, progettato specificamente per gli ambienti mobile.

Modifiche Chiave in Apollo Client 4.0

Apollo Client 4.0 disaccoppia gli export specifici di React in @apollo/client/react, supporta React 19 Suspense e il React Compiler, e sostituisce il monolitico ApolloError con classi di errore specifiche per un debugging migliore.

Configurazione di Apollo Client 4 in React Native

Il processo di installazione rimane semplice. Apollo Client 4.0 funziona sia con progetti Expo che con progetti React Native puri.

bash
# Installation
npm install @apollo/client graphql

L'inizializzazione del client richiede un HttpLink per le richieste di rete e un InMemoryCache per la gestione dello stato locale.

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 configurazione typePolicies gestisce la normalizzazione della cache per i dati paginati, un requisito comune nelle app mobile con scroll infinito.

Avvolgere l'App con ApolloProvider

Il pattern del provider connette Apollo Client all'albero dei componenti React. Deve essere posizionato al livello root, tipicamente in App.tsx o nel layout di 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 importa gli hook React da @apollo/client/react invece che dal punto di ingresso principale. Questa modifica riduce la dimensione del bundle quando il core client viene eseguito in contesti non-React.

Scrivere Query GraphQL Type-Safe

GraphQL Code Generator produce tipi TypeScript dallo schema, eliminando le discrepanze di tipo a runtime. L'installazione avviene insieme al plugin client.

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

La configurazione di codegen punta allo schema e specifica le posizioni di output.

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'esecuzione di npx graphql-codegen genera nodi documento tipizzati che l'hook useQuery consuma.

Recupero Dati con useQuery

L'hook useQuery gestisce gli stati di caricamento, gli errori e gli aggiornamenti della cache. Apollo Client 4.0 introduce l'API dataState per transizioni di stato più prevedibili.

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>Errore: {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 fetch policy cache-and-network visualizza immediatamente i dati in cache mentre aggiorna dal server in background. Questo pattern riduce la latenza percepita sulle reti mobili.

Pronto a superare i tuoi colloqui su React Native?

Pratica con i nostri simulatori interattivi, flashcards e test tecnici.

Mutation e Aggiornamenti Ottimistici

Le mutation modificano i dati del server e aggiornano la cache locale. Le risposte ottimistiche forniscono feedback immediato prima che il server confermi la modifica.

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 };
}

Il metodo cache.modify aggiorna direttamente i campi in cache senza rifare il fetch dell'intera query. Questo approccio minimizza le richieste di rete sulle connessioni cellulari.

Gestione degli Errori di Rete nelle App Mobile

Apollo Client 4.0 sostituisce il generico ApolloError con classi di errore specifiche. I metodi statici .is() permettono una gestione degli errori type-safe.

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>Connessione fallita. Controlla la tua connessione internet.</Text>
        <Button title="Riprova" onPress={onRetry} />
      </View>
    );
  }

  // GraphQL validation or resolver errors
  if (GraphQLErrors.is(error)) {
    const firstError = error.graphQLErrors[0];
    if (firstError?.extensions?.code === 'UNAUTHENTICATED') {
      return <Text>Sessione scaduta. Effettua nuovamente il login.</Text>;
    }
    return <Text>Richiesta fallita: {firstError?.message}</Text>;
  }

  return <Text>Qualcosa è andato storto</Text>;
}

Distinguere tra errori di rete ed errori GraphQL permette strategie di recupero diverse: riprovare per errori transitori, reindirizzare per problemi di autenticazione.

Supporto Offline con Persistenza della Cache

Le app mobile necessitano di accesso offline ai dati precedentemente recuperati. La libreria apollo3-cache-persist serializza la cache in 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
  });
}

Bisogna chiamare initializeCache prima di renderizzare l'app per ripristinare i dati in cache dal disco. Gli utenti vedono i contenuti recuperati più recentemente immediatamente, anche senza accesso alla rete.

Aggiornamenti in Tempo Reale con le Subscription GraphQL

Le subscription inviano eventi del server al client tramite WebSocket. Apollo Client 4.0 supporta il più recente protocollo 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 funzione split dirige le operazioni al trasporto appropriato in base al tipo di operazione.

Domande Comuni da Colloquio: React Native GraphQL

I colloqui tecnici spesso verificano la comprensione dei compromessi specifici per mobile di GraphQL. Le seguenti domande appaiono frequentemente nelle posizioni React Native.

Perché scegliere GraphQL rispetto a REST per le app mobile?

GraphQL riduce l'over-fetching restituendo solo i campi richiesti. Una singola query sostituisce più endpoint REST, riducendo i round-trip su connessioni cellulari ad alta latenza. Lo schema tipizzato permette la validazione a compile-time, rilevando le discrepanze API prima del runtime.

Come fa Apollo Client a mettere in cache i dati?

Apollo normalizza le risposte per __typename e id, memorizzando ogni entità una sola volta. Le query referenziano gli oggetti normalizzati tramite chiave di cache. Questa deduplicazione risparmia memoria e garantisce consistenza: aggiornare un prodotto in una lista lo aggiorna ovunque.

Quali fetch policy supporta Apollo Client?

PolicyComportamentoCaso d'Uso
cache-firstRestituisce cache se disponibile, altrimenti fetchDefault, minimizza le richieste
cache-and-networkRestituisce cache immediatamente, poi aggiorna da reteDati freschi con visualizzazione istantanea
network-onlySempre fetch, aggiorna cacheQuando i dati obsoleti sono inaccettabili
cache-onlyMai fetch, fallisce se non in cacheModalità offline
no-cacheFetch senza cachingDati sensibili

Come funzionano gli aggiornamenti ottimistici?

Il client predice il risultato della mutation e aggiorna la cache prima che il server risponda. Se il server restituisce un risultato diverso, Apollo sostituisce i dati ottimistici con la risposta effettiva. Se la mutation fallisce, Apollo torna allo stato precedente.

Cosa causa il problema N+1 in GraphQL?

I resolver annidati che recuperano dati correlati individualmente creano query N+1. Richiedere una lista di 50 prodotti con le loro categorie attiva 1 query prodotti più 50 query categorie. Il DataLoader lato server raggruppa queste in una singola query.

Come si gestiscono i token di autenticazione con Apollo Client?

L'approccio consigliato utilizza un Apollo Link per allegare i token a ogni richiesta.

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}` : '',
    },
  };
});

Questo link viene concatenato prima dell'HttpLink nella configurazione del client.

Debug di GraphQL in React Native

Apollo fornisce molteplici opzioni di debug per lo sviluppo React Native. L'estensione Apollo per VS Code include Client DevTools integrati che mostrano i contenuti della cache e la cronologia delle query.

Per il debug standalone, Flipper si integra con il plugin community react-native-apollo-devtools. Questo plugin ispeziona lo stato della cache, monitora le query in corso e riproduce le mutation.

L'ispezione di rete tramite React Native Debugger richiede l'abilitazione di "Debug JS Remotely". La tab Network mostra quindi i payload GraphQL con i body di request e response.

Punti Chiave per lo Sviluppo Mobile GraphQL

  • Apollo Client 4.0 riduce la dimensione del bundle del 20-30% attraverso il packaging ESM-first e gli export React disaccoppiati.
  • La fetch policy cache-and-network bilancia la visualizzazione istantanea con la freschezza dei dati su connessioni lente.
  • Gli aggiornamenti ottimistici forniscono feedback immediato; cache.modify evita refetch non necessari.
  • Le classi di errore tipizzate in Apollo Client 4.0 permettono una gestione specifica per errori di rete versus errori GraphQL.
  • La persistenza della cache con apollo3-cache-persist permette l'accesso offline ai dati precedentemente recuperati.
  • Le subscription GraphQL richiedono il protocollo graphql-ws e una configurazione split link.
  • Le domande da colloquio si concentrano su strategie di caching, fetch policy e compromessi specifici per mobile come la prevenzione N+1.

Inizia a praticare!

Metti alla prova le tue conoscenze con i nostri simulatori di colloquio e test tecnici.

Sfida del giorno

Sapresti trovare il bug in React Native?

Uno snippet reale, un bug nascosto, un tentativo al giorno. Senza account per provare.

Anthony Fillion-Maillet

Scritto da

Anthony Fillion-Maillet

Fondatore di SharpSkill

Sviluppatore fullstack da oltre 10 anni. Guida SharpSkill e risponde di tutto ciò che vi viene pubblicato.

Aggiornato il 20 agosto 2026

Tag

#react-native
#graphql
#apollo-client
#mobile
#api
#interview

Condividi

Articoli correlati