Fetch va Axios — React da HTTP so'rovlar
Muammodan boshlaylik
React komponentlari o'z ichidagi ma'lumotlar bilan ishlaydi —
useState, props. Lekin haqiqiy ilovalar serverdan ma'lumot
oladi: foydalanuvchilar ro'yxati, mahsulotlar, buyurtmalar.
Server bilan qanday gaplashiladi? HTTP so'rovlar orqali.
React ning o'zida bu uchun maxsus vosita yo'q. Brauzer
o'rnatilgan fetch API si bor — yoki axios kutubxonasini
o'rnatish mumkin.
Bu darsda ikkalasini ham ko'ramiz: qanday ishlaydi, farqlari nima, qachon qaysi birini tanlash kerak.
fetch — brauzer o'rnatilgan API
fetch — zamonaviy brauzerlarga o'rnatilgan funksiya.
Hech narsa o'rnatmasdan ishlatiladi. Promise qaytaradi.
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then((javob) => javob.json())
.then((malumot) => console.log(malumot));
Nima uchun ikki marta .then()? Birinchisi — HTTP javobini
oladi (sarlavhalar, status). Ikkinchisi — javob tanasini
(body) JSON ga o'giradi. Bu asinxron jarayon — shuning uchun
alohida .then().
React da fetch — useEffect bilan
Komponent yuklanganida server dan ma'lumot olish:
import { useState, useEffect } from 'react';
function Foydalanuvchi() {
const [malumot, setMalumot] = useState(null);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users/1')
.then((javob) => javob.json())
.then((data) => setMalumot(data));
}, []); // ← bo'sh array — faqat bir marta
if (!malumot) return <p>Yuklanmoqda...</p>;
return <h1>{malumot.name}</h1>;
}
Bu ishlaydi — lekin xato holati ko'rib chiqilmagan. Haqiqiy ilovada xatolarni ham boshqarish kerak.
fetch — xato boshqarish
fetch ning o'ziga xos muammosi bor: u faqat tarmoq xatosida
Promise ni rad etadi. Server 404, 500 qaytarsa — fetch
buni xato deb hisoblamaydi, ok: false deb javob beradi.
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/users/1')
.then((javob) => {
if (!javob.ok) {
throw new Error(`Server xatosi: ${javob.status}`);
}
return javob.json();
})
.then((data) => setMalumot(data))
.catch((err) => setXato(err.message));
}, []);
javob.ok — status 200-299 orasida bo'lsa true.
javob.status — aniq status kodi (404, 500 va h.k.).
async/await bilan yozish
.then() zanjirlari o'rniga async/await — o'qish osonroq:
import { useState, useEffect } from 'react';
function Foydalanuvchilar() {
const [royxat, setRoyxat] = useState([]);
const [yuklanmoqda, setYuklanmoqda] = useState(true);
const [xato, setXato] = useState('');
useEffect(() => {
async function malumotOl() {
try {
const javob = await fetch('https://jsonplaceholder.typicode.com/users');
if (!javob.ok) {
throw new Error(`Xato: ${javob.status}`);
}
const data = await javob.json();
setRoyxat(data);
} catch (err) {
setXato(err.message);
} finally {
setYuklanmoqda(false); // ← muvaffaqiyatli bo'lsa ham, xato bo'lsa ham
}
}
malumotOl();
}, []);
if (yuklanmoqda) return <p>Yuklanmoqda...</p>;
if (xato) return <p style={{ color: 'red' }}>Xato: {xato}</p>;
return (
<ul>
{royxat.map((f) => (
<li key={f.id}>{f.name}</li>
))}
</ul>
);
}
useEffect ichida async function e'lon qilinadi, keyin
chaqiriladi. Nima uchun to'g'ridan-to'g'ri async () => {} emas?
Chunki useEffect callback async bo'lsa Promise qaytaradi —
React bu Promise bilan nima qilishni bilmaydi va cleanup funksiyasini
kutadi.
Axios nima?
Axios — HTTP so'rovlar uchun mashhur kutubxona. fetch ga
qaraganda bir nechta qulay farqi bor.
O'rnatish:
npm install axios
Asosiy ishlatilish:
import axios from 'axios';
const javob = await axios.get('https://jsonplaceholder.typicode.com/users');
console.log(javob.data); // ← to'g'ridan-to'g'ri ma'lumot
fetch da ikki qadam — response.json() — kerak bo'lsa,
Axios da ma'lumot response.data da tayyor turibdi.
fetch vs Axios — farqlar
1. JSON avtomatik parse qilish:
// fetch — ikki qadam
const javob = await fetch(url);
const data = await javob.json(); // ← qo'shimcha qadam
// Axios — bir qadam
const javob = await axios.get(url);
const data = javob.data; // ← tayyor
2. Xato boshqarish:
// fetch — 404/500 ni xato deb hisoblamaydi
const javob = await fetch(url);
if (!javob.ok) throw new Error('Xato'); // ← qo'lda tekshirish
// Axios — 4xx/5xx da avtomatik xato chiqaradi
try {
await axios.get(url);
} catch (err) {
console.log(err.response.status); // 404, 500 va h.k.
}
3. So'rov bekor qilish:
// fetch — AbortController (50-darsda batafsil)
const controller = new AbortController();
fetch(url, { signal: controller.signal });
controller.abort();
// Axios — CancelToken yoki AbortController
const controller = new AbortController();
axios.get(url, { signal: controller.signal });
controller.abort();
4. Interceptor — so'rov/javobni ushlab olish:
// Axios da qulay interceptor API bor (85-darsda batafsil)
axios.interceptors.request.use((config) => {
config.headers.Authorization = `Bearer ${token}`;
return config;
});
fetch da interceptor yo'q — har so'rovga qo'lda header qo'shiladi.
5. Taraqqiyot (progress) kuzatish:
// Axios — fayl yuklashda progress
axios.post(url, fayl, {
onUploadProgress: (e) => {
const foiz = Math.round((e.loaded / e.total) * 100);
setProgress(foiz);
},
});
// fetch da bu mumkin emas (ReadableStream bilan murakkab yechim bor)
Axios — amaliy misol
import { useState, useEffect } from 'react';
import axios from 'axios';
function Mahsulotlar() {
const [mahsulotlar, setMahsulotlar] = useState([]);
const [yuklanmoqda, setYuklanmoqda] = useState(true);
const [xato, setXato] = useState('');
useEffect(() => {
async function malumotOl() {
try {
const javob = await axios.get('/api/mahsulotlar');
setMahsulotlar(javob.data);
} catch (err) {
if (err.response) {
// Server javob berdi, lekin 4xx/5xx
setXato(`Server xatosi: ${err.response.status}`);
} else if (err.request) {
// So'rov yuborildi, lekin javob kelmadi
setXato('Server bilan aloqa yo\'q');
} else {
// Boshqa xato
setXato(err.message);
}
} finally {
setYuklanmoqda(false);
}
}
malumotOl();
}, []);
if (yuklanmoqda) return <p>Yuklanmoqda...</p>;
if (xato) return <p style={{ color: 'red' }}>{xato}</p>;
return (
<ul>
{mahsulotlar.map((m) => (
<li key={m.id}>{m.nomi} — {m.narxi} so'm</li>
))}
</ul>
);
}
Axios instance — asosiy sozlamalar
Har so'rovda bir xil baseURL va headers yozmaslik uchun
Axios instance yaratiladi:
// src/api/axios.js
import axios from 'axios';
const api = axios.create({
baseURL: 'https://api.misol.uz', // ← asosiy URL
timeout: 10000, // ← 10 soniya kutish
headers: {
'Content-Type': 'application/json',
},
});
export default api;
// Komponentda — to'liq URL emas, faqat yo'l
import api from '../api/axios';
const javob = await api.get('/mahsulotlar'); // GET /mahsulotlar
const javob = await api.post('/buyurtma', data); // POST /buyurtma
const javob = await api.put('/mahsulot/42', data); // PUT /mahsulot/42
const javob = await api.delete('/mahsulot/42'); // DELETE /mahsulot/42
POST so'rov — ma'lumot yuborish
import { useState } from 'react';
import api from '../api/axios';
function MahsulotQoshish() {
const [nomi, setNomi] = useState('');
const [narxi, setNarxi] = useState('');
const [yuklanmoqda, setYuklanmoqda] = useState(false);
async function yuborish(e) {
e.preventDefault();
setYuklanmoqda(true);
try {
const javob = await api.post('/mahsulotlar', {
nomi,
narxi: Number(narxi),
});
console.log('Qo\'shildi:', javob.data);
setNomi('');
setNarxi('');
} catch (err) {
console.error('Xato:', err.message);
} finally {
setYuklanmoqda(false);
}
}
return (
<form onSubmit={yuborish}>
<input
value={nomi}
onChange={(e) => setNomi(e.target.value)}
placeholder="Mahsulot nomi"
/>
<input
value={narxi}
onChange={(e) => setNarxi(e.target.value)}
placeholder="Narxi"
type="number"
/>
<button type="submit" disabled={yuklanmoqda}>
{yuklanmoqda ? 'Saqlanmoqda...' : 'Saqlash'}
</button>
</form>
);
}
Tez-tez uchraydigan xatolar
1. fetch da javob.ok ni tekshirmaslik
// ❌ Xato — 404 da ham ma'lumot set qilinadi (undefined)
useEffect(() => {
fetch('/api/foydalanuvchi/999')
.then((j) => j.json())
.then((d) => setMalumot(d));
// Server "Not Found" xabarini qaytardi — bu ham JSON
// malumot = { message: "Not found" } — xato sifatida ko'rsatilmaydi
}, []);
// ✅ To'g'ri — ok tekshiriladi
useEffect(() => {
fetch('/api/foydalanuvchi/999')
.then((j) => {
if (!j.ok) throw new Error(`${j.status}`);
return j.json();
})
.then((d) => setMalumot(d))
.catch((err) => setXato(err.message));
}, []);
Sababi: fetch faqat tarmoq uzilganda xato chiqaradi.
Server 404 yoki 500 qaytarsa — bu fetch uchun muvaffaqiyatli
javob. response.ok ni tekshirishni unutsangiz, xato holatlari
ko'rinmaydi.
2. useEffect ichida to'g'ridan-to'g'ri async
// ❌ Xato — useEffect async bo'lmasligi kerak
useEffect(async () => {
const data = await fetch(url).then((j) => j.json());
setMalumot(data);
}, []);
// React konsolda ogohlantirish chiqaradi
// ✅ To'g'ri — ichida async funksiya e'lon qilib chaqirish
useEffect(() => {
async function olish() {
const data = await fetch(url).then((j) => j.json());
setMalumot(data);
}
olish();
}, []);
Sababi: useEffect callback yoki undefined, yoki cleanup
funksiyasi qaytarishi kerak. async funksiya Promise qaytaradi —
React uni cleanup funksiyasi deb bilmaydi va ogohlantirish chiqaradi.
3. Komponent unmount bo'lgandan keyin state set qilish
// ❌ Muammo — komponent yo'qolsa ham set qilishga uriniladi
useEffect(() => {
fetch(url)
.then((j) => j.json())
.then((d) => setMalumot(d)); // ← komponent yo'q bo'lsa xato
}, []);
// ✅ To'g'ri — AbortController bilan (50-darsda batafsil)
useEffect(() => {
const controller = new AbortController();
fetch(url, { signal: controller.signal })
.then((j) => j.json())
.then((d) => setMalumot(d))
.catch((err) => {
if (err.name !== 'AbortError') setXato(err.message);
});
return () => controller.abort(); // ← cleanup: so'rovni bekor qil
}, []);
Sababi: Foydalanuvchi sahifadan chiqib ketsa, komponent
unmount bo'ladi. Lekin so'rov davom etadi va javob kelganda
setMalumot chaqiriladi — yo'q komponentga. React konsol da
"Can't perform a React state update on an unmounted component"
ogohlantirishini beradi. Bu 50-darsda batafsil ko'riladi.
Qachon fetch, qachon Axios?
fetch ishlating:
- Kichik loyiha, minimal dependency kerak
- Faqat oddiy GET so'rovlar
- Bundle hajmini kamaytirish muhim
Axios ishlating:
- Ko'p so'rovlar, interceptor kerak
- Token avtomatik qo'shiladigan API
- Fayl yuklash va progress kuzatish
- Katta jamoa loyihasi — izchil xato boshqarish muhim
Amalda aksariyat React loyihalarida Axios yoki TanStack Query (51-55 darslar) ishlatiladi — fetch ni qo'lda ishlatish kamroq.
Xulosa
- fetch — brauzerga o'rnatilgan, o'rnatish shart emas
- Axios — qulay API, avtomatik JSON, xato boshqarish yaxshiroq
fetchdaresponse.okni tekshirish shart — aks holda 4xx xato ko'rinmaydiuseEffectichidaasync functione'lon qilib chaqiriladi- Axios instance —
baseURLva umumiy sozlamalar bir joyda - POST, PUT, DELETE —
axios.post(url, data),api.put(url, data),api.delete(url) - Komponent unmount bo'lganda so'rovni bekor qilish —
AbortController
Keyingi dars: 49-dars: Loading, Error, Success holatlari boshqarish