React Native dan GraphQL di 2026: Apollo Client, Query, dan Pertanyaan Wawancara

Tutorial lengkap React Native GraphQL dengan Apollo Client 4.0. Pelajari cara setup, query, mutation, caching, dan persiapan pertanyaan wawancara API mobile.

React Native dan GraphQL di 2026: Apollo Client, Query, dan Pertanyaan Wawancara

GraphQL telah menjadi layer API pilihan untuk aplikasi React Native yang membutuhkan pengambilan data fleksibel dan penggunaan jaringan yang efisien. Apollo Client 4.0, yang dirilis pada akhir 2025, menghadirkan arsitektur yang lebih ramping dengan ukuran bundle 20-30% lebih kecil serta dukungan TypeScript yang ditingkatkan khusus untuk lingkungan mobile.

Perubahan Utama Apollo Client 4.0

Apollo Client 4.0 memisahkan ekspor khusus React ke @apollo/client/react, mendukung React 19 Suspense dan React Compiler, serta mengganti ApolloError monolitik dengan class error spesifik untuk debugging yang lebih baik.

Menyiapkan Apollo Client 4 di React Native

Proses instalasi tetap sederhana. Apollo Client 4.0 bekerja dengan baik pada proyek Expo maupun React Native bare.

bash
# Installation
npm install @apollo/client graphql

Inisialisasi client membutuhkan HttpLink untuk request jaringan dan InMemoryCache untuk manajemen state lokal.

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];
            },
          },
        },
      },
    },
  }),
});

Konfigurasi typePolicies menangani normalisasi cache untuk data paginasi, kebutuhan umum dalam aplikasi mobile dengan infinite scroll.

Membungkus Aplikasi dengan ApolloProvider

Pola provider menghubungkan Apollo Client ke component tree React. Tempatkan di level root, biasanya di App.tsx atau 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 mengimpor React hooks dari @apollo/client/react daripada entry point utama. Perubahan ini mengurangi ukuran bundle ketika core client berjalan di konteks non-React.

GraphQL Code Generator menghasilkan tipe TypeScript dari schema, menghilangkan ketidakcocokan tipe saat runtime. Install bersama dengan client plugin.

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

Konfigurasi codegen menunjuk ke schema dan menentukan lokasi 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;

Menjalankan npx graphql-codegen menghasilkan typed document nodes yang dikonsumsi oleh hook useQuery.

Mengambil Data dengan useQuery

Hook useQuery mengelola loading states, error, dan cache updates. Apollo Client 4.0 memperkenalkan API dataState untuk transisi state yang lebih prediktabel.

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

Fetch policy cache-and-network menampilkan data dari cache secara langsung sembari memperbarui dari server. Pola ini mengurangi latency yang dirasakan pada jaringan mobile.

Siap menguasai wawancara React Native Anda?

Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.

Mutation dan Optimistic Updates

Mutation memodifikasi data server dan memperbarui cache lokal. Optimistic response memberikan feedback instan sebelum server mengkonfirmasi perubahan.

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

Metode cache.modify langsung memperbarui field yang di-cache tanpa mengambil ulang seluruh query. Pendekatan ini meminimalkan request jaringan pada koneksi seluler.

Menangani Network Error di Aplikasi Mobile

Apollo Client 4.0 mengganti ApolloError generik dengan class error spesifik. Metode statis .is() memungkinkan penanganan error yang 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>Connection failed. Check your internet.</Text>
        <Button title="Retry" 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 expired. Please log in again.</Text>;
    }
    return <Text>Request failed: {firstError?.message}</Text>;
  }

  return <Text>Something went wrong</Text>;
}

Membedakan network error dari GraphQL error memungkinkan strategi recovery yang berbeda: retry untuk kegagalan sementara, redirect untuk masalah autentikasi.

Dukungan Offline dengan Cache Persistence

Aplikasi mobile membutuhkan akses offline ke data yang sebelumnya diambil. Library apollo3-cache-persist menserialisasi cache ke 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
  });
}

Panggil initializeCache sebelum merender aplikasi untuk memulihkan data cache dari disk. Pengguna melihat konten yang terakhir diambil secara langsung, bahkan tanpa akses jaringan.

Update Real-Time dengan GraphQL Subscriptions

Subscription mendorong event server ke client melalui WebSocket. Apollo Client 4.0 mendukung protokol graphql-ws yang lebih baru.

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(),
});

Fungsi split mengarahkan operasi ke transport yang sesuai berdasarkan tipe operasi.

Pertanyaan Wawancara Umum: React Native GraphQL

Wawancara teknis sering menguji pemahaman tentang tradeoff spesifik mobile dari GraphQL. Pertanyaan-pertanyaan berikut sering muncul dalam posisi React Native.

Mengapa memilih GraphQL daripada REST untuk aplikasi mobile?

GraphQL mengurangi over-fetching dengan hanya mengembalikan field yang diminta. Satu query menggantikan beberapa endpoint REST, mengurangi round trip melalui koneksi seluler dengan latency tinggi. Schema yang typed memungkinkan validasi compile-time, menangkap ketidakcocokan API sebelum runtime.

Bagaimana Apollo Client meng-cache data?

Apollo menormalisasi response berdasarkan __typename dan id, menyimpan setiap entitas sekali. Query mereferensikan objek yang dinormalisasi berdasarkan cache key. Deduplikasi ini menghemat memori dan memastikan konsistensi: memperbarui produk di satu list memperbarui di semua tempat.

Fetch policy apa saja yang didukung Apollo Client?

PolicyPerilakuKasus Penggunaan
cache-firstKembalikan cache jika tersedia, jika tidak fetchDefault, meminimalkan request
cache-and-networkKembalikan cache langsung, lalu update dari networkData fresh dengan tampilan instan
network-onlySelalu fetch, update cacheKetika data basi tidak dapat diterima
cache-onlyTidak pernah fetch, gagal jika tidak di-cacheMode offline
no-cacheFetch tanpa cachingData sensitif

Bagaimana optimistic updates bekerja?

Client memprediksi hasil mutation dan memperbarui cache sebelum server merespons. Jika server mengembalikan hasil berbeda, Apollo mengganti data optimistic dengan response aktual. Jika mutation gagal, Apollo rollback ke state sebelumnya.

Apa yang menyebabkan masalah N+1 di GraphQL?

Nested resolver yang mengambil data terkait secara individual menciptakan N+1 query. Meminta daftar 50 produk dengan kategorinya memicu 1 query produk ditambah 50 query kategori. DataLoader sisi server mengelompokkan ini menjadi satu query.

Bagaimana menangani token autentikasi dengan Apollo Client?

Pendekatan yang direkomendasikan menggunakan Apollo Link untuk melampirkan token ke setiap request.

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

Rangkai link ini sebelum HttpLink dalam konfigurasi client.

Debugging GraphQL di React Native

Apollo menyediakan berbagai opsi debugging untuk pengembangan React Native. VS Code Apollo extension menyertakan Client DevTools built-in yang menampilkan konten cache dan riwayat query.

Untuk debugging standalone, Flipper terintegrasi dengan plugin komunitas react-native-apollo-devtools. Plugin ini memeriksa state cache, memantau query yang sedang berjalan, dan memutar ulang mutation.

Inspeksi jaringan melalui React Native Debugger memerlukan pengaktifan "Debug JS Remotely". Tab Network kemudian menampilkan payload GraphQL dengan body request dan response.

Poin-Poin Penting untuk Pengembangan Mobile GraphQL

  • Apollo Client 4.0 mengurangi ukuran bundle sebesar 20-30% melalui packaging ESM-first dan ekspor React yang dipisahkan.
  • Fetch policy cache-and-network menyeimbangkan tampilan instan dengan kesegaran data pada koneksi lambat.
  • Optimistic updates memberikan feedback langsung; cache.modify menghindari refetch yang tidak perlu.
  • Class error typed di Apollo Client 4.0 memungkinkan penanganan spesifik untuk kegagalan jaringan versus error GraphQL.
  • Cache persistence dengan apollo3-cache-persist memungkinkan akses offline ke data yang sebelumnya diambil.
  • GraphQL subscription membutuhkan protokol graphql-ws dan konfigurasi split link.
  • Pertanyaan wawancara fokus pada strategi caching, fetch policy, dan tradeoff spesifik mobile seperti pencegahan N+1.

Mulai berlatih!

Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.

Tantangan harian

Bisakah kamu menemukan bug di React Native?

Satu potongan kode nyata, satu bug tersembunyi, satu percobaan per hari. Tanpa akun untuk mencoba.

Anthony Fillion-Maillet

Ditulis oleh

Anthony Fillion-Maillet

Pendiri SharpSkill

Developer fullstack selama lebih dari 10 tahun. Ia menjalankan SharpSkill dan bertanggung jawab atas semua yang diterbitkan di sini.

Diperbarui 20 Agustus 2026

Bagikan

Artikel terkait