BrowserRouter, Routes, Route — tuzilishi
Muammodan boshlaylik
39-darsda React Router ni o'rnatdik va birinchi ilovani yozdik. Hamma narsa ishladi. Lekin bir nechta savol qoldi:
- Nima uchun
BrowserRouternimain.jsxda yozdik,App.jsxda emas? RoutesichidaRoutelar aniq ketma-ketlikda turadimi?/mahsulotlarva/mahsulotlar/yangi— ikkalasi ham mos kelib qolsa nima bo'ladi?- Bir nechta
Routesbloki bo'lishi mumkinmi?
Bu darsda shu savollarga javob beramiz — BrowserRouter, Routes
va Route ning ichki mexanizmlarini chuqurroq tushunib olamiz.
BrowserRouter qanday ishlaydi?
BrowserRouter — bu oddiy React komponent. U ichki React Context
yaratib, URL ma'lumotini barcha farzand komponentlarga uzatadi.
Shuning uchun Link, useNavigate, useParams kabi barcha
React Router elementlari BrowserRouter ichida bo'lishi shart —
ular o'sha kontekstdan ma'lumot oladi.
Hayotiy o'xshatma: BrowserRouter — shaharning asosiy pochta bo'limi.
Har bir xonadon (komponent) o'z manzilini undan oladi. Pochta bo'limi
bo'lmasa — hech qaysi xonadon o'z manzilinni bilmaydi.
BrowserRouter ni qayerga qo'yish kerak?
Qoidasi oddiy: barcha routing elementlarni o'rab oladigan eng tashqi komponentda bo'lishi kerak.
Odatda ikki xil yondashuv mavjud:
Variant 1 — main.jsx da:
// main.jsx
import { BrowserRouter } from 'react-router-dom';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')).render(
<BrowserRouter>
<App />
</BrowserRouter>
);
// App.jsx — faqat Routes va komponentlar
import { Routes, Route } from 'react-router-dom';
function App() {
return (
<Routes>
<Route path="/" element={<Bosh />} />
<Route path="/haqida" element={<Haqida />} />
</Routes>
);
}
Variant 2 — App.jsx da:
// main.jsx — oddiy
import App from './App';
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
// App.jsx — BrowserRouter shu yerda
import { BrowserRouter, Routes, Route } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Bosh />} />
<Route path="/haqida" element={<Haqida />} />
</Routes>
</BrowserRouter>
);
}
Qaysi variant to'g'ri? Ikkalasi ham ishlaydi. Lekin birinchi
variant — main.jsx da — ko'proq tarqalgan. Sababi: App.jsx
ni test qilish osonlashadi (test vaqtida boshqa Router turini
o'rab qo'ysa bo'ladi, masalan MemoryRouter).
Routes qanday ishlaydi?
Routes — "tarjimon". U joriy URL ni oladi va ichidagi barcha
Route larni yuqoridan pastga ko'rib chiqadi. Birinchi mos
kelganini tanlaydi va faqat o'shanisini render qiladi.
<Routes>
<Route path="/" element={<Bosh />} />
<Route path="/haqida" element={<Haqida />} />
<Route path="/mahsulotlar" element={<Mahsulotlar />} />
<Route path="*" element={<TopilmadI />} />
</Routes>
URL /haqida bo'lsa:
"/"— mos keladimi? v6 da aniq moslashish bo'ladi, shuning uchun yo'q"/haqida"— mos keladi!<Haqida />render bo'ladi- Qolganlar tekshirilmaydi
Bu v5 dan farqli: v5 da <Switch> ketma-ket tekshirar va
exact kalit so'zi kerak edi. v6 da bu avtomatik.
v5 va v6 farqi — muhim
Agar internetda eski qo'llanmalarni ko'rsangiz, shunday kod ko'rasiz:
// ❌ Bu v5 — hozir ishlamaydi
import { Switch, Route } from 'react-router-dom';
<Switch>
<Route exact path="/" component={Bosh} />
<Route path="/haqida" component={Haqida} />
</Switch>
v6 da:
<Switch>→<Routes>ga o'zgartirildicomponent={...}→element={<Komponent />}ga o'zgartirildiexactprop yo'q — v6 da avtomatik aniq moslashish
// ✅ Bu v6 — to'g'ri
import { Routes, Route } from 'react-router-dom';
<Routes>
<Route path="/" element={<Bosh />} />
<Route path="/haqida" element={<Haqida />} />
</Routes>
Route — batafsil
Route — bitta qoidani belgilaydi: "bu URL bo'lsa, bu komponentni ko'rsat."
path prop
URL manzilini bildiradi. Bir nechta xil yozilishi mumkin:
{/* Aniq manzil */}
<Route path="/mahsulotlar" element={<Mahsulotlar />} />
{/* Dinamik parametr — : bilan */}
<Route path="/mahsulot/:id" element={<MahsulotDetali />} />
{/* Bir nechta parametr */}
<Route path="/kategoriya/:slug/mahsulot/:id" element={<Detali />} />
{/* Istalgan qolgan manzil — 404 */}
<Route path="*" element={<TopilmadI />} />
element prop
Ko'rsatiladigan komponentni bildiradi. JSX ko'rinishida yoziladi:
{/* ✅ To'g'ri — JSX */}
<Route path="/haqida" element={<Haqida />} />
{/* ❌ Xato — komponent sifatida */}
<Route path="/haqida" element={Haqida} />
{/* ❌ Xato — v5 usuli */}
<Route path="/haqida" component={Haqida} />
Nima uchun JSX? Chunki element={<Haqida />} ko'rinishida
props uzatish oson bo'ladi:
<Route path="/profil" element={<Profil foydalanuvchi={joriyFoydalanuvchi} />} />
Index Route — bosh sahifa uchun maxsus yondashuv
Nested routing (ichma-ich) da bosh sahifani ko'rsatish uchun
index prop ishlatiladi:
<Routes>
<Route path="/dashboard" element={<Dashboard />}>
<Route index element={<DashboardBosh />} /> {/* /dashboard */}
<Route path="statistika" element={<Statistika />} /> {/* /dashboard/statistika */}
<Route path="sozlamalar" element={<Sozlamalar />} /> {/* /dashboard/sozlamalar */}
</Route>
</Routes>
index prop li Route — path yo'q, lekin ota Route ning URL iga
to'g'ri kelganda ko'rsatiladi. Bu nested routing da foydali —
45-darsda batafsil ko'ramiz.
Bir nechta Routes bloki
Odatda bir ilovada bitta <Routes> bloki bo'ladi. Lekin bir
nechta ham bo'lishi mumkin — masalan, bir xil sahifada ikkita
mustaqil panel:
function App() {
return (
<div className="layout">
{/* Asosiy panel */}
<main>
<Routes>
<Route path="/" element={<Bosh />} />
<Route path="/mahsulotlar" element={<Mahsulotlar />} />
</Routes>
</main>
{/* Yon panel — o'z route lari bilan */}
<aside>
<Routes>
<Route path="/mahsulotlar" element={<FiltrPanel />} />
</Routes>
</aside>
</div>
);
}
/mahsulotlar da asosiy panel ham, yon panel ham ko'rsatiladi.
Bosh sahifada faqat asosiy panel ko'rinadi. Bu kamdan-kam ishlatiladi,
lekin mumkin.
To'liq misol — barcha tushunchalar bilan
// src/App.jsx
import { Routes, Route } from 'react-router-dom';
import Nav from './components/Nav';
import Bosh from './pages/Bosh';
import Haqida from './pages/Haqida';
import Mahsulotlar from './pages/Mahsulotlar';
import MahsulotDetali from './pages/MahsulotDetali';
import TopilmadI from './pages/TopilmadI';
function App() {
return (
<>
<Nav />
<Routes>
{/* Bosh sahifa */}
<Route path="/" element={<Bosh />} />
{/* Oddiy sahifalar */}
<Route path="/haqida" element={<Haqida />} />
{/* Ro'yxat sahifasi */}
<Route path="/mahsulotlar" element={<Mahsulotlar />} />
{/* Dinamik sahifa — :id o'zgaruvchi */}
<Route path="/mahsulot/:id" element={<MahsulotDetali />} />
{/* 404 — har doim eng oxirida */}
<Route path="*" element={<TopilmadI />} />
</Routes>
</>
);
}
export default App;
// src/main.jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')).render(
<BrowserRouter>
<App />
</BrowserRouter>
);
// src/pages/TopilmadI.jsx
import { Link } from 'react-router-dom';
function TopilmadI() {
return (
<div>
<h1>404 — Sahifa topilmadi</h1>
<p>Bunday sahifa mavjud emas.</p>
<Link to="/">Bosh sahifaga qaytish</Link>
</div>
);
}
export default TopilmadI;
Tez-tez uchraydigan xatolar
1. element ga JSX o'rniga funksiya uzatish
// ❌ Xato — render bo'lmaydi
<Route path="/haqida" element={Haqida} />
// ❌ Xato — v5 usuli
<Route path="/haqida" component={Haqida} />
// ✅ To'g'ri — JSX
<Route path="/haqida" element={<Haqida />} />
Sababi: element prop React elementi (JSX) kutadi, komponent
funksiyasini emas. element={Haqida} — bu funksiyaga havola,
React uni ko'rsatishni bilmaydi.
2. path="*" ni birinchi qo'yish
// ❌ Xato — * birinchi bo'lsa, hamma URL shu yerga tushadi
<Routes>
<Route path="*" element={<TopilmadI />} />
<Route path="/" element={<Bosh />} />
<Route path="/haqida" element={<Haqida />} />
</Routes>
// ✅ To'g'ri — * har doim eng oxirida
<Routes>
<Route path="/" element={<Bosh />} />
<Route path="/haqida" element={<Haqida />} />
<Route path="*" element={<TopilmadI />} />
</Routes>
Sababi: Routes yuqoridan pastga qaraydi va birinchi mos
kelganini oladi. * istalgan URL ga mos keladi — birinchi tursa,
boshqa Route larga o'tilmaydi. Har doim eng oxirida bo'lsin.
3. path da bosh slashshiz yozish
// ❌ Xato — slash yo'q
<Route path="haqida" element={<Haqida />} />
// ✅ To'g'ri — slash bilan
<Route path="/haqida" element={<Haqida />} />
Sababi: Bosh / siz path nisbiy yo'l sifatida tushuniladi.
Asosiy (top-level) route lar har doim / bilan boshlanishi kerak.
Faqat nested route larda (ota Route ichidagi) slash tushirib qoldiriladi.
4. BrowserRouter ni ikki marta o'rash
// main.jsx — BrowserRouter bor
<BrowserRouter>
<App />
</BrowserRouter>
// App.jsx — yana BrowserRouter — ❌ XATO
function App() {
return (
<BrowserRouter>
<Routes>...</Routes>
</BrowserRouter>
);
}
Sababi: Ikki BrowserRouter — ikki mustaqil routing konteksti.
Ular bir-biriga zid keladi. React konsolda xato chiqaradi.
BrowserRouter faqat bir joyda bo'lsin.
Xulosa
- BrowserRouter — bir marta, eng tashqarida o'raladi (
main.jsxda tavsiya) - Routes — barcha Route larni ko'rib chiqib, bitta mosini tanlaydi
- Route —
path+element— qaysi URL da qaysi komponent element={<Komponent />}— JSX ko'rinishida, funksiya sifatida emaspath="*"— 404 uchun, har doim eng oxirida- v6 da
exactkerak emas — avtomatik aniq moslashish - Bir nechta
Routesbloki mumkin, lekin kamdan-kam kerak bo'ladi
Keyingi dars: 41-dars: Link, NavLink — a tegidan farqi, active holat