React Native y GraphQL en 2026: Apollo Client, Consultas y Preguntas de Entrevista

Guía completa para integrar GraphQL y Apollo Client 4.0 en aplicaciones React Native. Configuración, consultas tipadas, mutaciones optimistas y preguntas técnicas de entrevista.

React Native y GraphQL con Apollo Client

GraphQL se ha convertido en la capa de API preferida para aplicaciones React Native que requieren obtención de datos flexible y uso eficiente de la red. Apollo Client 4.0, lanzado a finales de 2025, introduce una arquitectura más ligera con bundles 20-30% más pequeños y soporte mejorado de TypeScript diseñado específicamente para entornos móviles.

Cambios Clave de Apollo Client 4.0

Apollo Client 4.0 desacopla las exportaciones específicas de React a @apollo/client/react, soporta React 19 Suspense y el React Compiler, y reemplaza el monolítico ApolloError con clases de error específicas para mejor depuración.

Configuración de Apollo Client 4 en React Native

El proceso de instalación sigue siendo sencillo. Apollo Client 4.0 funciona tanto con Expo como con proyectos bare de React Native.

bash
# Installation
npm install @apollo/client graphql

La inicialización del cliente requiere un HttpLink para solicitudes de red y un InMemoryCache para gestión de estado 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 configuración typePolicies maneja la normalización de caché para datos paginados, un requisito común en aplicaciones móviles con scroll infinito.

Envolviendo la Aplicación con ApolloProvider

El patrón provider conecta Apollo Client al árbol de componentes React. Se coloca a nivel raíz, típicamente en App.tsx o el layout de 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 los hooks de React desde @apollo/client/react en lugar del punto de entrada principal. Este cambio reduce el tamaño del bundle cuando el cliente core se ejecuta en contextos no-React.

Escribiendo Consultas GraphQL con Tipado

GraphQL Code Generator produce tipos TypeScript desde el esquema, eliminando incompatibilidades de tipos en tiempo de ejecución. Se instala junto con el plugin del cliente.

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

La configuración del codegen apunta al esquema y especifica las ubicaciones de salida.

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;

Ejecutar npx graphql-codegen genera nodos de documento tipados que el hook useQuery consume.

Obteniendo Datos con useQuery

El hook useQuery gestiona estados de carga, errores y actualizaciones de caché. Apollo Client 4.0 introduce la API dataState para transiciones de estado más predecibles.

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 política de fetch cache-and-network muestra datos en caché inmediatamente mientras refresca desde el servidor. Este patrón reduce la latencia percibida en redes móviles.

¿Listo para aprobar tus entrevistas de React Native?

Practica con nuestros simuladores interactivos, flashcards y tests técnicos.

Mutaciones y Actualizaciones Optimistas

Las mutaciones modifican datos del servidor y actualizan el caché local. Las respuestas optimistas proporcionan feedback instantáneo antes de que el servidor confirme el cambio.

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

El método cache.modify actualiza directamente campos en caché sin volver a consultar la query completa. Este enfoque minimiza las solicitudes de red en conexiones celulares.

Manejo de Errores de Red en Aplicaciones Móviles

Apollo Client 4.0 reemplaza el genérico ApolloError con clases de error específicas. Los métodos estáticos .is() permiten manejo de errores con tipado seguro.

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>Conexión fallida. Verifica tu conexión a internet.</Text>
        <Button title="Reintentar" onPress={onRetry} />
      </View>
    );
  }

  // GraphQL validation or resolver errors
  if (GraphQLErrors.is(error)) {
    const firstError = error.graphQLErrors[0];
    if (firstError?.extensions?.code === 'UNAUTHENTICATED') {
      return <Text>Sesión expirada. Por favor inicia sesión nuevamente.</Text>;
    }
    return <Text>Solicitud fallida: {firstError?.message}</Text>;
  }

  return <Text>Algo salió mal</Text>;
}

Distinguir errores de red de errores GraphQL permite diferentes estrategias de recuperación: reintentar para fallos transitorios, redirigir para problemas de autenticación.

Soporte Offline con Persistencia de Caché

Las aplicaciones móviles necesitan acceso offline a datos previamente obtenidos. La biblioteca apollo3-cache-persist serializa el caché a 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
  });
}

Llamar a initializeCache antes de renderizar la aplicación restaura los datos en caché desde el disco. Los usuarios ven su último contenido obtenido inmediatamente, incluso sin acceso a la red.

Actualizaciones en Tiempo Real con Subscriptions de GraphQL

Las subscriptions envían eventos del servidor al cliente a través de WebSocket. Apollo Client 4.0 soporta el protocolo más nuevo 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 función split dirige las operaciones al transporte apropiado según el tipo de operación.

Preguntas Comunes de Entrevista: React Native GraphQL

Las entrevistas técnicas frecuentemente exploran la comprensión de los compromisos específicos de GraphQL en móviles. Las siguientes preguntas aparecen frecuentemente en posiciones de React Native.

¿Por qué elegir GraphQL sobre REST para aplicaciones móviles?

GraphQL reduce el over-fetching al retornar solo los campos solicitados. Una sola consulta reemplaza múltiples endpoints REST, reduciendo viajes de ida y vuelta en conexiones celulares de alta latencia. El esquema tipado permite validación en tiempo de compilación, detectando incompatibilidades de API antes de la ejecución.

¿Cómo cachea datos Apollo Client?

Apollo normaliza las respuestas por __typename e id, almacenando cada entidad una sola vez. Las consultas referencian objetos normalizados por clave de caché. Esta deduplicación ahorra memoria y asegura consistencia: actualizar un producto en una lista lo actualiza en todas partes.

¿Qué políticas de fetch soporta Apollo Client?

PolíticaComportamientoCaso de Uso
cache-firstRetorna caché si está disponible, sino fetchPor defecto, minimiza solicitudes
cache-and-networkRetorna caché inmediatamente, luego actualiza desde redDatos frescos con display instantáneo
network-onlySiempre fetch, actualiza cachéCuando datos obsoletos son inaceptables
cache-onlyNunca fetch, falla si no está en cachéModo offline
no-cacheFetch sin cachearDatos sensibles

¿Cómo funcionan las actualizaciones optimistas?

El cliente predice el resultado de la mutación y actualiza el caché antes de que el servidor responda. Si el servidor retorna un resultado diferente, Apollo reemplaza los datos optimistas con la respuesta real. Si la mutación falla, Apollo revierte al estado anterior.

¿Qué causa un problema N+1 en GraphQL?

Los resolvers anidados que obtienen datos relacionados individualmente crean consultas N+1. Solicitar una lista de 50 productos con sus categorías dispara 1 consulta de productos más 50 consultas de categorías. DataLoader del lado del servidor agrupa estas en una sola consulta.

¿Cómo manejar tokens de autenticación con Apollo Client?

El enfoque recomendado usa un Apollo Link para adjuntar tokens a cada solicitud.

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

Encadenar este link antes del HttpLink en la configuración del cliente.

Depuración de GraphQL en React Native

Apollo proporciona múltiples opciones de depuración para desarrollo React Native. La extensión Apollo para VS Code incluye DevTools del Cliente integradas que muestran contenidos del caché e historial de consultas.

Para depuración independiente, Flipper se integra con el plugin comunitario react-native-apollo-devtools. Este plugin inspecciona el estado del caché, observa consultas en vuelo y reproduce mutaciones.

La inspección de red a través de React Native Debugger requiere habilitar "Debug JS Remotely". La pestaña Network entonces muestra payloads GraphQL con cuerpos de solicitud y respuesta.

Puntos Clave para Desarrollo GraphQL Móvil

  • Apollo Client 4.0 reduce el tamaño del bundle en 20-30% mediante empaquetado ESM-first y exportaciones React desacopladas.
  • La política de fetch cache-and-network balancea display instantáneo con frescura de datos en conexiones lentas.
  • Las actualizaciones optimistas proporcionan feedback inmediato; cache.modify evita refetches innecesarios.
  • Las clases de error tipadas en Apollo Client 4.0 permiten manejo específico para fallos de red versus errores GraphQL.
  • La persistencia de caché con apollo3-cache-persist habilita acceso offline a datos previamente obtenidos.
  • Las subscriptions GraphQL requieren el protocolo graphql-ws y configuración de split link.
  • Las preguntas de entrevista se enfocan en estrategias de caché, políticas de fetch y compromisos específicos móviles como prevención N+1.

¡Empieza a practicar!

Pon a prueba tu conocimiento con nuestros simuladores de entrevista y tests técnicos.

Reto diario

¿Sabrías detectar el bug en React Native?

Un fragmento real, un bug oculto, un intento al día. Sin cuenta para probar.

Anthony Fillion-Maillet

Escrito por

Anthony Fillion-Maillet

Fundador de SharpSkill

Desarrollador fullstack desde hace más de 10 años. Dirige SharpSkill y responde por todo lo que se publica aquí.

Actualizado el 20 de agosto de 2026

Etiquetas

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

Compartir

Artículos relacionados