fetch: built-in, đủ dùng cho 80% case. Yếu điểm: không timeout default (phải dùng AbortController), không retry, parse JSON cần .json() rời.
axios: API gọn hơn, transformer built-in, interceptor cho auth header và refresh token, timeout config dễ.
const api = axios.create({ baseURL: 'https://api.example.com', timeout: 10_000 })
api.interceptors.request.use((config) => {
config.headers.Authorization = `Bearer ${getToken()}`
return config
})Retry / backoff: dùng axios-retry hoặc viết qua TanStack Query (built-in retry: 3, retryDelay: exponential).
Offline detection: @react-native-community/netinfo:
import NetInfo from '@react-native-community/netinfo'
NetInfo.addEventListener((state) => console.log(state.isConnected, state.type))Pattern thường thấy: wrap toàn app trong NetInfoProvider → expose isOnline. TanStack Query onlineManager.setEventListener để pause query khi offline. Hiển thị banner "You are offline" toàn cục. Mutation queue: khi offline, lưu request vào MMKV; khi online lại, replay.
RN-specific gotcha: trên iOS simulator, NetInfo.fetch().isConnected có thể trả true ngay cả khi không có internet thật — luôn test trên device.