React Router nima, o'rnatish, asosiy tushunchalar

~15 daq · React · Routing

Muammodan boshlaylik

Siz birinchi React loyihangizni yozdingiz. Hammasi ishlayapti — komponentlar chiqmoqda, state o'zgarmoqda. Lekin bir kun shunday holat yuz berdi:

Foydalanuvchi profiliga o'tmoqchi bo'lib brauzerda /profil deb yozdi. Brauzer "404 — sahifa topilmadi" dedi.

Nima bo'ldi? React da hamma narsa bitta index.html fayl ichida. Server /profil deb kelganda — bunday fayl yo'q. Faqat index.html bor.

Yana bir holat: foydalanuvchi "Mahsulotlar" tugmasini bosganda sahifa to'liq yangilandi. Savatcbahadagi barcha mahsulotlar yo'qoldi. Sababi — oddiy <a href> HTML tegidir, brauzer yangi sahifa yuklab oldi.

Bu ikki muammo SPA (Single Page Application) ning asosiy og'riq nuqtasi. React Router aynan shu muammolarni hal qilish uchun yaratilgan.


React Router nima?

React Router — React uchun routing kutubxonasi. U ikkita narsa qiladi:

  1. Brauzer URL ini kuzatadi
  2. Joriy URL ga mos kelgan komponentni ekranda ko'rsatadi

Muhimi: sahifa HAQIQATDA yangilanmaydi. index.html bir xil qoladi. Faqat ekrandagi komponent almashinadi. Bu — Client-Side Routing.


Hayotiy o'xshatma

Tasavvur qiling: katta mehmonxona. Siz retsepsiyaga kelib "305-xona" deysiz. Retsepsionist sizni o'sha xonaga olib boradi. Keyin "oshxona" deysiz — boshqa joyga olib boradi.

Mehmonxona binosi o'zgarmadi. Siz ham qaytadan kirib chiqmadingiz. Faqat turadigan joningiz almashinadi.

React Router ham xuddi shunday ishlaydi:

  • Mehmonxona = sizning React ilovangiz (index.html)
  • Retsepsionist = React Router
  • Xona/joy nomi = URL (/profil, /mahsulotlar, /sozlamalar)
  • Xona = komponent (<Profil />, <Mahsulotlar />, <Sozlamalar />)

URL o'zgarganda React Router "qaysi komponent ko'rsatilsin?" deb qaraydi va o'sha komponentni ekranga chiqaradi. Sahifa yangilanmaydi.


Nima uchun React ning o'zi bu ishni qilmaydi?

React — faqat UI yaratish uchun. URL, navigatsiya, tarix (history) — bu brauzer va server bilan bog'liq mavzular. React bu vazifalarni ataylab o'z ichiga olmagan: har bir kutubxona o'z ishini qilsin degan prinsip.

Shuning uchun routing uchun alohida kutubxona kerak. React Router bugungi kunda bu sohadagi eng keng tarqalgan tanlov. Uning raqobatchilari ham bor (TanStack Router, Wouter), lekin React Router hujjatlari, jamiyati va ekotizimi bilan yetakchi o'rinda turadi.


O'rnatish

npm install react-router-dom

Nima uchun react-router-dom, react-router emas? Chunki react-router — platforma tanlamagan yadro. react-router-dom — brauzerga xos qo'shimchalar bilan birga keladi: BrowserRouter, Link, NavLink va boshqalar. Biz brauzer ilovasi yozayapmiz, shuning uchun react-router-dom kerak.

Versiyani tekshirish:

npm list react-router-dom

Bu kurs React Router v6 asosida. v5 bilan sintaksis farqlanadi — <Switch> va <Redirect> yo'q, o'rniga <Routes> va <Navigate>.


Asosiy qismlar

React Router uchta asosiy qismdan iborat. Ularni birma-bir tanib chiqamiz:

BrowserRouter

Butun ilovani "routing rejimiga" o'tkazadigan o'ram komponent. Faqat bir marta, eng tashqi qatlamda o'raladi.

import { BrowserRouter } from 'react-router-dom';

<BrowserRouter>
  <App />
</BrowserRouter>

BrowserRouter brauzerning History API sidan foydalanadi — shuning uchun URL lar chiroyli ko'rinadi: /mahsulotlar, /profil/42.

Routes va Route

Qaysi URL da qaysi komponent ko'rsatilishini belgilaydi. Route har doim Routes ichida bo'ladi.

import { Routes, Route } from 'react-router-dom';

<Routes>
  <Route path="/" element={<Bosh />} />
  <Route path="/haqida" element={<Haqida />} />
  <Route path="/mahsulotlar" element={<Mahsulotlar />} />
</Routes>

Routes barcha Route larni ko'rib chiqadi va joriy URL ga eng mos kelganini tanlaydi. Faqat bitta Route ishlaydi.

Link

Sahifalar orasida o'tish uchun. HTML <a> tegiga o'xshab ko'rinadi, lekin sahifani yangilamaydi.

import { Link } from 'react-router-dom';

<Link to="/mahsulotlar">Mahsulotlar</Link>

Birinchi to'liq misol

Papkalar tuzilishi:

src/
  pages/
    Bosh.jsx
    Haqida.jsx
    Mahsulotlar.jsx
  components/
    Nav.jsx
  App.jsx
  main.jsx

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>      {/* ← bir marta, eng tashqarida */}
    <App />
  </BrowserRouter>
);

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';

function App() {
  return (
    <>
      <Nav />  {/* ← Routes dan tashqarida — har sahifada ko'rinadi */}

      <Routes>
        <Route path="/" element={<Bosh />} />
        <Route path="/haqida" element={<Haqida />} />
        <Route path="/mahsulotlar" element={<Mahsulotlar />} />
        <Route path="*" element={<h2>404 — sahifa topilmadi</h2>} />
      </Routes>
    </>
  );
}

export default App;

components/Nav.jsx:

import { Link } from 'react-router-dom';

function Nav() {
  return (
    <nav>
      <Link to="/">Bosh sahifa</Link>
      <Link to="/haqida">Haqida</Link>
      <Link to="/mahsulotlar">Mahsulotlar</Link>
    </nav>
  );
}

export default Nav;

pages/Bosh.jsx:

function Bosh() {
  return <h1>Bosh sahifaga xush kelibsiz!</h1>;
}

export default Bosh;

pages/Haqida.jsx:

function Haqida() {
  return <h1>Biz haqimizda</h1>;
}

export default Haqida;

pages/Mahsulotlar.jsx:

function Mahsulotlar() {
  return <h1>Mahsulotlar ro'yxati</h1>;
}

export default Mahsulotlar;

Endi /mahsulotlar ga o'tganda <Nav /> o'zgarmasdan qoladi, faqat uning ostidagi <Mahsulotlar /> ko'rinadi. Sahifa yangilanmaydi.


Route turlari

Aniq manzil

<Route path="/mahsulotlar" element={<Mahsulotlar />} />

Faqat /mahsulotlar ga to'g'ri keladi.

Dinamik parametr

<Route path="/mahsulot/:id" element={<MahsulotDetali />} />

:id — o'zgaruvchi qism. /mahsulot/1, /mahsulot/99, /mahsulot/telefon — hammasi ushbu Route ga tushadi. id qiymatini useParams hook i bilan olinadi (43-dars).

404 sahifa

<Route path="*" element={<TopilmadI />} />

* — hech qaysi Route mos kelmasa ishlaydi. Har doim <Routes> ning eng oxirida joylashtiriladi.


BrowserRouter vs HashRouter

Ikkala variant ham mavjud, lekin farqi bor:

BrowserRouter — zamonaviy va tavsiya etilgan:

https://sayt.uz/mahsulotlar
https://sayt.uz/profil/42

HashRouter — eski usul, # belgisi bilan:

https://sayt.uz/#/mahsulotlar
https://sayt.uz/#/profil/42

Nima uchun HashRouter mavjud? Ba'zi hosting xizmatlar (masalan, GitHub Pages standart sozlamada) faqat index.html ni biladi. /#/mahsulotlar bo'lsa, server faqat index.html ni yuboradi va # dan keyingi qismni JavaScript o'qiydi.

Lekin sizning serveringiz bor bo'lsa yoki Vercel/Netlify da deploy qilsangiz — har doim BrowserRouter ishlating.


Tez-tez uchraydigan xatolar

1. Link ni BrowserRouter dan tashqarida ishlatish

// ❌ Xato
function App() {
  return (
    <>
      <Link to="/">Bosh</Link>   {/* Router yo'q! */}
      <BrowserRouter>
        <Routes>...</Routes>
      </BrowserRouter>
    </>
  );
}
// ✅ To'g'ri
function App() {
  return (
    <BrowserRouter>
      <Link to="/">Bosh</Link>
      <Routes>...</Routes>
    </BrowserRouter>
  );
}

Sababi: Link o'z ichki holatini BrowserRouter dan oladi. Router konteksti bo'lmasa, Link nima qilishini bilmaydi va konsolda "You should not use <Link> outside a <Router>" xatosi chiqadi. Link va barcha routing elementlar BrowserRouter ichida bo'lishi shart.


2. <a href> ni <Link> o'rniga ishlatish

// ❌ Xato — sahifa to'liq yangilanadi
<a href="/mahsulotlar">Mahsulotlar</a>
// ✅ To'g'ri — faqat komponent almashinadi
<Link to="/mahsulotlar">Mahsulotlar</Link>

Sababi: <a href> bilan brauzer serverga yangi HTTP so'rov yuboradi. Butun React ilovasi qayta yuklanadi — JavaScript qayta o'qiladi, barcha state yo'qoladi (savatcha, forma qiymatlari, scroll pozitsiyasi, hamma narsa). <Link> esa History API orqali URL ni o'zgartiradi, React davom etadi.


3. Routes ni unutish

// ❌ Xato — v6 da Route yolg'iz ishlamaydi
<BrowserRouter>
  <Route path="/" element={<Bosh />} />
  <Route path="/haqida" element={<Haqida />} />
</BrowserRouter>
// ✅ To'g'ri — Route har doim Routes ichida
<BrowserRouter>
  <Routes>
    <Route path="/" element={<Bosh />} />
    <Route path="/haqida" element={<Haqida />} />
  </Routes>
</BrowserRouter>

Sababi: React Router v6 da <Route> mustaqil ishlolmaydi. <Routes> barcha <Route> larni ko'rib chiqib, faqat bitta mosini tanlaydi. Bu v5 dagi <Switch> ning yangi, kuchliroq variantidir.


4. BrowserRouter ni ikki marta o'rash

// ❌ Xato — main.jsx da BrowserRouter bor,
//           App.jsx da ham qo'shib qo'yilgan
function App() {
  return (
    <BrowserRouter>    {/* ← bu ortiqcha */}
      <Routes>...</Routes>
    </BrowserRouter>
  );
}

Sababi: BrowserRouter brauzer tarixini kuzatadi. Ikkita BrowserRouter bo'lsa, ikkita mustaqil router paydo bo'ladi — ular bir-biriga zid keladi. Konsolda "You cannot render a <Router> inside another <Router>" xatosi chiqadi.

Yechim: BrowserRouter faqat main.jsx da, eng tashqarida — bir marta.


Xulosa

  • React Router — URL va komponentlar orasidagi ko'prik
  • Client-Side Routing — URL o'zgaradi, sahifa yangilanmaydi
  • BrowserRouter — main.jsx da bir marta o'raladi
  • Routes + Route — qaysi URL da qaysi komponent aniqlanadi
  • Link — <a href> o'rniga, sahifani yangilamaydi
  • path="*" — 404 sahifasi uchun
  • O'rnatish: npm install react-router-dom

Keyingi dars: 40-dars: BrowserRouter, Routes, Route — tuzilishi