useParams — URL parametrlarni olish
Muammodan boshlaylik
Siz mahsulotlar do'konini yozyapsiz. Har bir mahsulot uchun alohida
sahifa bo'lishi kerak: /mahsulot/1, /mahsulot/42, /mahsulot/99.
Agar har bir mahsulot uchun alohida Route yozsangiz:
<Route path="/mahsulot/1" element={<Mahsulot1 />} />
<Route path="/mahsulot/2" element={<Mahsulot2 />} />
<Route path="/mahsulot/3" element={<Mahsulot3 />} />
// ... mingta mahsulot uchun mingta Route?
Bu albatta mumkin emas. Bir bitta Route yozib, ichidagi raqamni dinamik qilib olish kerak:
<Route path="/mahsulot/:id" element={<MahsulotDetali />} />
Endi /mahsulot/1 ham, /mahsulot/999 ham shu Route ga tushadi.
Lekin komponent ichida o'sha id ni qanday olamiz?
Buning uchun useParams hook i bor.
useParams nima?
useParams — URL dagi dinamik parametrlarni o'qib beruvchi hook.
Route da :id, :slug, :kategoriya kabi : bilan belgilangan
qismlar — dinamik parametrlar. useParams shu parametrlarni
ob'ekt ko'rinishida qaytaradi.
Hayotiy o'xshatma: pochta indeksi. Har bir xonadonning o'z
indeksi bor — 100001, 100002, 100003. Pochta xizmati bir qoida
bilan ishlaydi: "indeksga yetkazib ber". useParams esa joriy
xonadonning indeksini aytib beradi.
Asosiy ishlatilish
Route da parametr aniqlanadi:
// App.jsx
<Route path="/mahsulot/:id" element={<MahsulotDetali />} />
Komponent ichida useParams bilan olinadi:
import { useParams } from 'react-router-dom';
function MahsulotDetali() {
const { id } = useParams(); // ← URL dagi :id ni oladi
return <h1>Mahsulot raqami: {id}</h1>;
}
/mahsulot/42 da id === "42".
/mahsulot/telefon da id === "telefon".
Muhim: parametr har doim string
useParams dan kelgan barcha qiymatlar — string turida.
Agar raqam kerak bo'lsa, o'zingiz o'girishingiz kerak:
const { id } = useParams();
// id — "42" (string)
console.log(typeof id); // "string"
// Raqamga o'girish
const raqamliId = Number(id); // 42
const raqamliId2 = parseInt(id); // 42
const raqamliId3 = +id; // 42
Server ga so'rov yuborayotganda ko'pincha raqam kerak bo'ladi:
function MahsulotDetali() {
const { id } = useParams();
useEffect(() => {
mahsulotniOlish(Number(id)); // ← raqamga o'girildi
}, [id]);
}
Bir nechta parametr
Route da bir nechta dinamik parametr bo'lishi mumkin:
<Route path="/kategoriya/:slug/mahsulot/:id" element={<Detali />} />
function Detali() {
const { slug, id } = useParams();
// /kategoriya/telefonlar/mahsulot/42 da:
// slug === "telefonlar"
// id === "42"
return (
<div>
<p>Kategoriya: {slug}</p>
<p>Mahsulot ID: {id}</p>
</div>
);
}
Amaliy misol — server dan ma'lumot olish
import { useParams } from 'react-router-dom';
import { useEffect, useState } from 'react';
function MahsulotDetali() {
const { id } = useParams();
const [mahsulot, setMahsulot] = useState(null);
const [yuklanmoqda, setYuklanmoqda] = useState(true);
const [xato, setXato] = useState('');
useEffect(() => {
setYuklanmoqda(true);
fetch(`https://api.misol.uz/mahsulotlar/${id}`)
.then((res) => {
if (!res.ok) throw new Error('Mahsulot topilmadi');
return res.json();
})
.then((malumot) => {
setMahsulot(malumot);
setYuklanmoqda(false);
})
.catch((err) => {
setXato(err.message);
setYuklanmoqda(false);
});
}, [id]); // ← id o'zgarganda qayta so'rov yuboriladi
if (yuklanmoqda) return <p>Yuklanmoqda...</p>;
if (xato) return <p>Xato: {xato}</p>;
if (!mahsulot) return <p>Mahsulot topilmadi</p>;
return (
<div>
<h1>{mahsulot.nomi}</h1>
<p>{mahsulot.narxi} so'm</p>
<p>{mahsulot.tavsifi}</p>
</div>
);
}
export default MahsulotDetali;
id dependency array da — /mahsulot/42 dan /mahsulot/99 ga
o'tganda sahifa qayta yuklanmaydi, lekin useEffect yangi id
bilan ishga tushadi va yangi mahsulot yuklanadi.
Ro'yxat + detal sahifa pattern
Keng tarqalgan pattern: ro'yxat sahifasida elementni bossang, detal sahifasiga o'tish.
// App.jsx
<Routes>
<Route path="/mahsulotlar" element={<Mahsulotlar />} />
<Route path="/mahsulot/:id" element={<MahsulotDetali />} />
</Routes>
// pages/Mahsulotlar.jsx
import { Link } from 'react-router-dom';
const mahsulotlar = [
{ id: 1, nomi: 'iPhone 15', narxi: 12000000 },
{ id: 2, nomi: 'Samsung S24', narxi: 10000000 },
{ id: 3, nomi: 'Pixel 8', narxi: 9000000 },
];
function Mahsulotlar() {
return (
<div>
<h1>Mahsulotlar</h1>
{mahsulotlar.map((m) => (
<div key={m.id}>
<Link to={`/mahsulot/${m.id}`}>{m.nomi}</Link>
<span> — {m.narxi.toLocaleString()} so'm</span>
</div>
))}
</div>
);
}
export default Mahsulotlar;
// pages/MahsulotDetali.jsx
import { useParams, Link } from 'react-router-dom';
const mahsulotlar = [
{ id: 1, nomi: 'iPhone 15', narxi: 12000000, tavsifi: 'Apple ning yangi modeli' },
{ id: 2, nomi: 'Samsung S24', narxi: 10000000, tavsifi: 'Android ning eng yaxshisi' },
{ id: 3, nomi: 'Pixel 8', narxi: 9000000, tavsifi: "Google ning telefoni" },
];
function MahsulotDetali() {
const { id } = useParams();
const mahsulot = mahsulotlar.find((m) => m.id === Number(id)); // ← Number() muhim
if (!mahsulot) {
return (
<div>
<p>Mahsulot topilmadi</p>
<Link to="/mahsulotlar">Ro'yxatga qaytish</Link>
</div>
);
}
return (
<div>
<Link to="/mahsulotlar">← Orqaga</Link>
<h1>{mahsulot.nomi}</h1>
<p>{mahsulot.narxi.toLocaleString()} so'm</p>
<p>{mahsulot.tavsifi}</p>
</div>
);
}
export default MahsulotDetali;
Tez-tez uchraydigan xatolar
1. Parametrni raqamga o'girmaslik
const { id } = useParams();
// ❌ Xato — string va raqam solishtirilmoqda
const mahsulot = mahsulotlar.find((m) => m.id === id);
// m.id === 42 (number), id === "42" (string) — mos kelmaydi!
// ✅ To'g'ri — Number() bilan o'girish
const mahsulot = mahsulotlar.find((m) => m.id === Number(id));
Sababi: useParams har doim string qaytaradi. Massivdagi
id lar raqam bo'lsa, === solishtirish noto'g'ri natija beradi.
42 === "42" — JavaScriptda false.
2. useEffect dependency array dan id ni tushirib qoldirish
// ❌ Xato — id dependency array da yo'q
useEffect(() => {
mahsulotniYukla(id);
}, []); // ← bo'sh array
// ✅ To'g'ri
useEffect(() => {
mahsulotniYukla(id);
}, [id]); // ← id o'zgarganda qayta ishlaydi
Sababi: /mahsulot/1 dan /mahsulot/2 ga o'tganda komponent
qayta yaratilmaydi — faqat id o'zgaradi. Dependency array da
id bo'lmasa, useEffect qayta ishlamaydi — eskicha ma'lumot
ko'rinib qoladi.
3. Route da parametr nomini noto'g'ri yozish
// Route da
<Route path="/mahsulot/:mahsulotId" element={<MahsulotDetali />} />
// ❌ Xato — noto'g'ri nom
const { id } = useParams(); // undefined!
// ✅ To'g'ri — Route dagi nom bilan bir xil
const { mahsulotId } = useParams();
Sababi: useParams Route dagi :nom ni kalit sifatida
ishlatadi. Nom mos kelmasa — undefined qaytadi.
4. useParams ni Route tashqarisida ishlatish
// ❌ Xato — bu komponent hech qaysi Route da emas
function Sarlavha() {
const { id } = useParams(); // undefined
return <h1>Mahsulot {id}</h1>;
}
// ✅ To'g'ri — Route ichida render bo'ladigan komponent yoki uning farzandi
<Route path="/mahsulot/:id" element={<MahsulotDetali />} />
// MahsulotDetali ichida yoki uning farzandida useParams ishlaydi
function MahsulotDetali() {
return <Sarlavha />; // Sarlavha ham useParams ishlatishi mumkin
}
function Sarlavha() {
const { id } = useParams(); // ✅ ishlaydi — Route farzandi
return <h1>Mahsulot {id}</h1>;
}
Sababi: useParams React Router kontekstidan foydalanadi.
Bu kontekst faqat BrowserRouter va tegishli Route ichida mavjud.
Xulosa
useParams— URL dagi:parametrqiymatlarini olish uchun- Barcha qiymatlar string — raqam kerak bo'lsa
Number()ishlatish - Bir nechta parametr bo'lsa — hammasi ob'ektda qaytadi
useEffectdependency array gaidni qo'shish shart- Parametr nomi Route dagi
:nombilan aynan bir xil bo'lishi kerak
Keyingi dars: 44-dars: useSearchParams — query parametrlar bilan ishlash