Offline rejim — tarmoq holati, kesh bilan ishlash
Muammodan boshlaylik
Foydalanuvchi metroda ilovani ochdi. Internet yo'q. Ilova:
- Bo'sh oq ekran va cheksiz spinner
- Yoki "Network request failed" — qizil yozuv
Lekin u kecha shu katalogni ko'rgan edi! Nima uchun ilova o'sha ma'lumotni ko'rsatmayapti? Va u yozgan izoh — internet qaytganda yuborilishi mumkin edi.
Yaxshi mobil ilova internet bo'lmaganda qisman ishlashda davom etadi. Bu — offline-first yondashuv.
1. Tarmoq holatini bilish
npx expo install @react-native-community/netinfo
import { useNetInfo } from '@react-native-community/netinfo';
export function OfflineBanner() {
const { isConnected, isInternetReachable } = useNetInfo();
const offline = isConnected === false || isInternetReachable === false;
if (!offline) return null;
return (
<View style={{ backgroundColor: '#475569', padding: 8 }}>
<Text style={{ color: 'white', textAlign: 'center', fontSize: 13 }}>
Internet aloqasi yo'q — saqlangan ma'lumotlar ko'rsatilmoqda
</Text>
</View>
);
}
isConnected— Wi-Fi yoki mobil tarmoqqa ulanganmiisInternetReachable— haqiqatan internetga chiqa oladimi (Wi-Fi bor, lekin internet yo'q — kafe Wi-Fi si)- Boshida
nullbo'lishi mumkin — "hali noma'lum"; uni offline deb hisoblamang
2. Ma'lumotni offline ko'rsatish — kesh saqlash
TanStack Query (32-dars) keshni xotirada saqlaydi — ilova yopilsa yo'qoladi. Uni diskka saqlash:
npm install @tanstack/react-query-persist-client @tanstack/query-async-storage-persister
// app/_layout.tsx
import { QueryClient } from '@tanstack/react-query';
import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client';
import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persister';
import AsyncStorage from '@react-native-async-storage/async-storage';
const queryClient = new QueryClient({
defaultOptions: {
queries: {
gcTime: 1000 * 60 * 60 * 24, // 24 soat — keshda saqlash muddati
staleTime: 60_000,
networkMode: 'offlineFirst',
},
},
});
const persister = createAsyncStoragePersister({ storage: AsyncStorage });
export default function RootLayout() {
return (
<PersistQueryClientProvider client={queryClient} persistOptions={{ persister, maxAge: 1000 * 60 * 60 * 24 }}>
<OfflineBanner />
<Stack />
</PersistQueryClientProvider>
);
}
Endi:
- Ilova ochildi, internet yo'q → kechagi katalog darhol ko'rinadi
- Internet qaytdi →
onlineManager(32-dars) fonda yangilaydi gcTime— kesh qancha yashashi;persistOptions.maxAgedan kichik bo'lmasin
networkMode: 'offlineFirst' — so'rovni avval sinaydi; tarmoq yo'q bo'lsa — keshdagi ma'lumot bilan ishlaydi va tarmoq qaytishini kutadi (xato bermaydi).
3. Offline yozish — navbat
Foydalanuvchi offline holatda "yoqtirish" ni bosdi yoki izoh yozdi. Variantlar:
A. Mutatsiyalarni to'xtatib turish (TanStack Query)
useMutation({
mutationKey: ['izoh'],
mutationFn: (d: { postId: number; matn: string }) => apiPost('/izohlar', d),
networkMode: 'offlineFirst',
});
Offline bo'lsa — mutatsiya to'xtatiladi (isPaused) va internet qaytganda avtomatik yuboriladi. Persist bilan birga — ilova yopilib ochilsa ham (to'xtatilgan mutatsiyalar uchun setMutationDefaults va resumePausedMutations sozlanadi).
Interfeysda optimistik yangilash (32-dars) — izoh darhol ro'yxatda ko'rinadi, kulrang "yuborilmoqda" belgisi bilan.
B. O'z navbatingiz
Oddiy holatlar uchun — AsyncStorage dagi navbat:
// lib/navbat.ts
type Vazifa = { id: string; yol: string; body: unknown };
export async function navbatgaQosh(v: Omit<Vazifa, 'id'>) {
const navbat = await xotira.get<Vazifa[]>('navbat', []);
await xotira.set('navbat', [...navbat, { ...v, id: String(Date.now()) }]);
}
export async function navbatniYubor() {
const navbat = await xotira.get<Vazifa[]>('navbat', []);
const qolgan: Vazifa[] = [];
for (const v of navbat) {
try {
await apiPost(v.yol, v.body);
} catch {
qolgan.push(v); // muvaffaqiyatsiz — keyingi safar
}
}
await xotira.set('navbat', qolgan);
}
// Internet qaytganda
NetInfo.addEventListener((s) => { if (s.isConnected) navbatniYubor(); });
[!WARNING] Navbatdagi so'rovlar idempotent bo'lishi kerak: tarmoq uzilsa, so'rov serverga yetib borgan, lekin javob kelmagan bo'lishi mumkin — va u qayta yuboriladi. Har bir vazifaga noyob
idbering va server shuidbilan takroriy so'rovni e'tiborsiz qoldirsin (MySQL kursidagi to'lov callback misoli, 60-dars).
4. Qaysi amallar offline ishlashi kerak
Hamma narsani offline qilish shart emas. Savol: "foydalanuvchi internet bo'lmaganda nima qilishni kutadi?"
| Amal | Offline |
|---|---|
| Avval ko'rilgan katalog, profil, buyurtmalar | ✅ Keshdan ko'rsatish |
| Eslatma, izoh, "yoqtirish" | ✅ Navbatga, keyin yuborish |
| Savatga qo'shish | ✅ Mahalliy (Zustand persist) |
| To'lov | ❌ Faqat onlayn — aniq xabar bilan |
| Ro'yxatdan o'tish, kirish | ❌ Faqat onlayn |
| Yangi qidiruv | ⚠️ Faqat keshdagilar orasida yoki "internet kerak" |
Onlayn talab qiladigan amallarda — tugmani o'chirib, sababini ko'rsating:
const { isConnected } = useNetInfo();
<Tugma matn={isConnected === false ? "Internet kerak" : "To'lash"} disabled={isConnected === false} onPress={tolash} />
5. Sinash
- Telefonda parvoz rejimi — eng oddiy sinov
- Android emulyator — Extended Controls → Cellular → Network type / Signal
- iOS — Settings → Developer → Network Link Conditioner ("3G", "Very Bad Network")
- Sekin internetda sinang — "internet yo'q" dan ko'ra ko'proq uchraydi va ko'proq muammo keltirib chiqaradi
Nima uchun shunday?
Nima uchun offline rejimga bunchalik e'tibor beriladi — hozir hamma joyda internet bor-ku?
"Hamma joyda" — faqat dasturchining ofisida. Haqiqiy foydalanuvchi liftda, metroda, viloyat yo'lida, binoning yerto'lasida, roumingda, oyning oxirida trafik tugaganda. Mobil tarmoq — doim "ba'zan ishlaydi" holatda. Internet uzilganda yiqiladigan ilova — foydalanuvchi uchun "buzilgan" ilova. Offline-first yondashuv esa ilovani tez ham qiladi: kesh darhol ko'rsatiladi, tarmoq faqat fonda yangilaydi.
Xulosa
Eslab qoling:
useNetInfo()—isConnected,isInternetReachable;null— noma'lum- Offline banner — foydalanuvchiga holatni ayting
- TanStack Query + persister + AsyncStorage — kesh diskda, ilova offline ochiladi
networkMode: 'offlineFirst',gcTime— offline xatti-harakat- Offline yozish — to'xtatilgan mutatsiyalar yoki o'z navbatingiz; idempotentlik majburiy
- To'lov, kirish — faqat onlayn; tugmani o'chirib, sababini ko'rsating
- Parvoz rejimida va sekin tarmoqda sinang
Keyingi dars
37-dars: 5-6 bo'lim mashqlari — yangiliklar ilovasi