React Native และ GraphQL ในปี 2026: Apollo Client, Query และคำถามสัมภาษณ์
บทเรียน React Native GraphQL ฉบับสมบูรณ์พร้อม Apollo Client 4.0 เรียนรู้การตั้งค่า query, mutation, caching และเตรียมพร้อมสำหรับคำถามสัมภาษณ์ API มือถือ

GraphQL กลายเป็น API layer ที่ได้รับความนิยมสำหรับแอปพลิเคชัน React Native ที่ต้องการการดึงข้อมูลที่ยืดหยุ่นและการใช้งานเครือข่ายที่มีประสิทธิภาพ Apollo Client 4.0 ซึ่งเปิดตัวในปลายปี 2025 นำเสนอสถาปัตยกรรมที่กระชับขึ้นพร้อมขนาด bundle ที่ลดลง 20-30% และการรองรับ TypeScript ที่ปรับปรุงเฉพาะสำหรับสภาพแวดล้อมมือถือ
Apollo Client 4.0 แยก export เฉพาะ React ไปที่ @apollo/client/react รองรับ React 19 Suspense และ React Compiler และแทนที่ ApolloError แบบ monolithic ด้วย error class เฉพาะสำหรับการ debug ที่ดีขึ้น
การตั้งค่า Apollo Client 4 ใน React Native
กระบวนการติดตั้งยังคงตรงไปตรงมา Apollo Client 4.0 ทำงานได้ทั้งโปรเจกต์ Expo และ React Native bare
# Installation
npm install @apollo/client graphqlการเริ่มต้น client ต้องการ HttpLink สำหรับ request เครือข่าย และ InMemoryCache สำหรับการจัดการ state ภายในเครื่อง
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];
},
},
},
},
},
}),
});การกำหนดค่า typePolicies จัดการการ normalize cache สำหรับข้อมูลแบบ pagination ซึ่งเป็นข้อกำหนดทั่วไปในแอปมือถือที่มี infinite scroll
การครอบแอปพลิเคชันด้วย ApolloProvider
Pattern provider เชื่อมต่อ Apollo Client กับ component tree ของ React วางไว้ที่ระดับ root โดยปกติใน App.tsx หรือ layout ของ Expo Router
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 import React hooks จาก @apollo/client/react แทนที่จะเป็น entry point หลัก การเปลี่ยนแปลงนี้ลดขนาด bundle เมื่อ core client ทำงานในบริบทที่ไม่ใช่ React
การเขียน GraphQL Query แบบ Type-Safe
GraphQL Code Generator สร้าง TypeScript types จาก schema กำจัดความไม่ตรงกันของ type ในขณะ runtime ติดตั้งพร้อมกับ client plugin
# Install codegen tools
npm install -D @graphql-codegen/cli @graphql-codegen/client-presetการกำหนดค่า codegen ชี้ไปที่ schema และระบุตำแหน่ง output
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;การรัน npx graphql-codegen จะสร้าง typed document nodes ที่ถูกใช้โดย hook useQuery
การดึงข้อมูลด้วย useQuery
Hook useQuery จัดการ loading states, errors และ cache updates Apollo Client 4.0 แนะนำ API dataState สำหรับการเปลี่ยน state ที่คาดการณ์ได้มากขึ้น
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 แสดงข้อมูลจาก cache ทันทีในขณะที่รีเฟรชจาก server Pattern นี้ลด latency ที่รับรู้ได้บนเครือข่ายมือถือ
พร้อมที่จะพิชิตการสัมภาษณ์ React Native แล้วหรือยังครับ?
ฝึกฝนด้วยตัวจำลองแบบโต้ตอบ, flashcards และแบบทดสอบเทคนิคครับ
Mutation และ Optimistic Updates
Mutation แก้ไขข้อมูล server และอัปเดต cache ภายในเครื่อง Optimistic response ให้ feedback ทันทีก่อนที่ server จะยืนยันการเปลี่ยนแปลง
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 };
}Method cache.modify อัปเดต field ที่ cache ไว้โดยตรงโดยไม่ต้อง fetch query ทั้งหมดใหม่ วิธีนี้ลด request เครือข่ายบนการเชื่อมต่อมือถือ
การจัดการ Network Error ในแอปมือถือ
Apollo Client 4.0 แทนที่ ApolloError ทั่วไปด้วย error class เฉพาะ Method static .is() ช่วยให้การจัดการ error แบบ type-safe เป็นไปได้
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>;
}การแยกแยะ network error จาก GraphQL error ช่วยให้ใช้กลยุทธ์การกู้คืนที่แตกต่างกัน: retry สำหรับความล้มเหลวชั่วคราว, redirect สำหรับปัญหาการยืนยันตัวตน
การรองรับ Offline ด้วย Cache Persistence
แอปมือถือต้องการการเข้าถึง offline สำหรับข้อมูลที่ fetch ไว้ก่อนหน้า Library apollo3-cache-persist serialize cache ไปยัง AsyncStorage
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
});
}เรียก initializeCache ก่อน render แอปเพื่อกู้คืนข้อมูล cache จาก disk ผู้ใช้เห็นเนื้อหาที่ fetch ล่าสุดทันที แม้ไม่มีการเข้าถึงเครือข่าย
การอัปเดต Real-Time ด้วย GraphQL Subscriptions
Subscription ส่ง event จาก server ไปยัง client ผ่าน WebSocket Apollo Client 4.0 รองรับ protocol graphql-ws ที่ใหม่กว่า
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(),
});ฟังก์ชัน split กำหนดเส้นทาง operation ไปยัง transport ที่เหมาะสมตามประเภท operation
คำถามสัมภาษณ์ที่พบบ่อย: React Native GraphQL
การสัมภาษณ์ทางเทคนิคมักทดสอบความเข้าใจเกี่ยวกับ tradeoff เฉพาะมือถือของ GraphQL คำถามต่อไปนี้ปรากฏบ่อยในตำแหน่ง React Native
ทำไมเลือก GraphQL แทน REST สำหรับแอปมือถือ?
GraphQL ลด over-fetching โดยส่งคืนเฉพาะ field ที่ร้องขอ Query เดียวแทนที่ endpoint REST หลายตัว ลด round trip ผ่านการเชื่อมต่อมือถือที่มี latency สูง Schema ที่มี type ช่วยให้ validation ตอน compile-time จับความไม่ตรงกันของ API ก่อน runtime
Apollo Client cache ข้อมูลอย่างไร?
Apollo normalize response ตาม __typename และ id โดยเก็บแต่ละ entity หนึ่งครั้ง Query อ้างอิง object ที่ normalize แล้วตาม cache key การขจัดความซ้ำซ้อนนี้ประหยัดหน่วยความจำและรับประกันความสอดคล้อง: การอัปเดตสินค้าในรายการหนึ่งจะอัปเดตทุกที่
Apollo Client รองรับ fetch policy อะไรบ้าง?
| Policy | พฤติกรรม | กรณีการใช้งาน |
|---|---|---|
cache-first | ส่งคืน cache ถ้ามี ไม่งั้น fetch | ค่าเริ่มต้น ลด request |
cache-and-network | ส่งคืน cache ทันที จากนั้นอัปเดตจาก network | ข้อมูลใหม่พร้อมการแสดงผลทันที |
network-only | fetch เสมอ อัปเดต cache | เมื่อข้อมูลเก่าไม่เป็นที่ยอมรับ |
cache-only | ไม่ fetch เลย fail ถ้าไม่มี cache | โหมด offline |
no-cache | Fetch โดยไม่ cache | ข้อมูลที่ละเอียดอ่อน |
Optimistic updates ทำงานอย่างไร?
Client ทำนายผลลัพธ์ mutation และอัปเดต cache ก่อน server ตอบกลับ ถ้า server ส่งคืนผลลัพธ์ที่แตกต่าง Apollo แทนที่ข้อมูล optimistic ด้วย response จริง ถ้า mutation ล้มเหลว Apollo rollback ไปยัง state ก่อนหน้า
อะไรทำให้เกิดปัญหา N+1 ใน GraphQL?
Nested resolver ที่ fetch ข้อมูลที่เกี่ยวข้องทีละตัวสร้าง N+1 query การร้องขอรายการสินค้า 50 รายการพร้อมหมวดหมู่ trigger 1 query สินค้าบวก 50 query หมวดหมู่ DataLoader ฝั่ง server รวมสิ่งเหล่านี้เป็น query เดียว
จัดการ token ยืนยันตัวตนกับ Apollo Client อย่างไร?
วิธีที่แนะนำใช้ Apollo Link เพื่อแนบ token กับทุก request
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}` : '',
},
};
});เชื่อมต่อ link นี้ก่อน HttpLink ในการกำหนดค่า client
การ Debug GraphQL ใน React Native
Apollo มีตัวเลือก debug หลายอย่างสำหรับการพัฒนา React Native VS Code Apollo extension รวม Client DevTools ในตัวที่แสดงเนื้อหา cache และประวัติ query
สำหรับการ debug แบบ standalone, Flipper ผสานรวมกับ plugin ชุมชน react-native-apollo-devtools Plugin นี้ตรวจสอบ state cache, ติดตาม query ที่กำลังทำงาน และ replay mutation
การตรวจสอบเครือข่ายผ่าน React Native Debugger ต้องเปิด "Debug JS Remotely" Tab Network จากนั้นจะแสดง payload GraphQL พร้อม body request และ response
ประเด็นสำคัญสำหรับการพัฒนา Mobile GraphQL
- Apollo Client 4.0 ลดขนาด bundle 20-30% ผ่านการ package แบบ ESM-first และแยก export React
- Fetch policy
cache-and-networkสมดุลการแสดงผลทันทีกับความสดของข้อมูลบนการเชื่อมต่อช้า - Optimistic updates ให้ feedback ทันที;
cache.modifyหลีกเลี่ยง refetch ที่ไม่จำเป็น - Error class ที่มี type ใน Apollo Client 4.0 ช่วยให้จัดการเฉพาะสำหรับความล้มเหลวเครือข่ายเทียบกับ error GraphQL
- Cache persistence ด้วย
apollo3-cache-persistช่วยให้เข้าถึง offline สำหรับข้อมูลที่ fetch ไว้ก่อนหน้า - GraphQL subscription ต้องการ protocol
graphql-wsและการกำหนดค่า split link - คำถามสัมภาษณ์มุ่งเน้นกลยุทธ์ caching, fetch policy และ tradeoff เฉพาะมือถือเช่นการป้องกัน N+1
เริ่มฝึกซ้อมเลย!
ทดสอบความรู้ของคุณด้วยตัวจำลองสัมภาษณ์และแบบทดสอบเทคนิคครับ
คุณหาบั๊กใน React Native เจอไหม
โค้ดจริงหนึ่งชิ้น บั๊กที่ซ่อนอยู่หนึ่งจุด วันละหนึ่งครั้ง ลองได้โดยไม่ต้องมีบัญชี

เขียนโดย
Anthony Fillion-Mailletผู้ก่อตั้ง SharpSkill
เป็นนักพัฒนาฟูลสแตกมากว่า 10 ปี ดูแล SharpSkill และรับผิดชอบทุกสิ่งที่เผยแพร่ที่นี่
อัปเดตเมื่อ 20 สิงหาคม 2569
แชร์
บทความที่เกี่ยวข้อง

คู่มือพัฒนาแอป React Native 2026: สร้างแอป Production และคำถามสัมภาษณ์
คู่มือครบถ้วนสำหรับการพัฒนาแอป React Native 2026 ครอบคลุม New Architecture, Expo SDK 56, Hermes V1 และคำถามสัมภาษณ์สำหรับนักพัฒนา React Native

การพัฒนาแอปพลิเคชัน React Native 2026: คู่มือฉบับสมบูรณ์และคำถามสัมภาษณ์
คู่มือครบถ้วนสำหรับการพัฒนาแอปพลิเคชัน React Native ในปี 2026 เรียนรู้ New Architecture, JSI, Fabric, TurboModules และคำถามสัมภาษณ์ที่พบบ่อย

React Native 0.87 และ SwiftPM ในปี 2026: การ Build iOS สมัยใหม่และคำถามสัมภาษณ์
คู่มือฉบับสมบูรณ์ React Native 0.87 พร้อมการรองรับ Swift Package Manager สำหรับ build iOS เรียนรู้การย้ายจาก CocoaPods, Strict TypeScript API และคำถามสัมภาษณ์ทางเทคนิค