Link, NavLink — a tegidan farqi, active holat

~15 daq · React · Routing

Muammodan boshlaylik

40-darsda <Link> ni ishlatdik. Lekin foydalanuvchi qaysi sahifada turganini ko'rsatmoqchi bo'ldingiz. Masalan, navigatsiyada faol havola qorayib yoki tagiga chiziq chiqib ko'rinishi kerak.

<Link> bilan bu mumkinmi? Mumkin — lekin qo'lda URL ni tekshirib, class qo'shishingiz kerak:

const manzil = useLocation();

<Link
  to="/mahsulotlar"
  className={manzil.pathname === '/mahsulotlar' ? 'active' : ''}
>
  Mahsulotlar
</Link>

Bu yaxshi usul emas — har havola uchun bir xil kodni qayta yozasiz.

<NavLink> aynan shu muammo uchun yaratilgan. U faol holatni avtomatik aniqlaydi va class qo'shib beradi.


Link nima?

<Link> — HTML <a> tegining React Router versiyasi. U URL ni o'zgartiradi, lekin sahifani yangilamaydi.

Brauzerda ko'rinishi oddiy <a> teg bilan bir xil — sichqoncha bilan ustiga borganda manzil ko'rinadi, o'ng tugma bilan yangi tabda ochish ishlaydi.

Hayotiy o'xshatma: <Link> — mehmonxona liftidagi tugmalar. Qaysi qavatga borishni biladi, lekin qaysi qavatda turganingizni yorqin ko'rsatmaydi. <NavLink> esa faol tugmani yondirib qo'yadi.


Link — asosiy ishlatilish

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

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

to prop — turli xil yozilishi

{/* Oddiy matn — eng ko'p ishlatiladigan */}
<Link to="/mahsulotlar">Mahsulotlar</Link>

{/* Ob'ekt ko'rinishida — query va hash bilan */}
<Link to={{ pathname: '/mahsulotlar', search: '?tur=yangi' }}>
  Yangi mahsulotlar
</Link>

{/* -1 — orqaga qaytish (brauzer tarixi) */}
<Link to={-1}>Orqaga</Link>

replace prop

Odatda <Link> brauzer tarixiga yangi yozuv qo'shadi. replace bilan eski yozuv almashtiriladi — "orqaga" tugmasi oldingi sahifaga emas, undan oldingi sahifaga olib boradi.

{/* Tarixga qo'shadi — standart */}
<Link to="/profil">Profil</Link>

{/* Tarixni almashtiradi */}
<Link to="/kirish" replace>Kirish</Link>

Qachon kerak? Login sahifasidan keyin foydalanuvchi "orqaga" bossa login sahifasiga qaytib qolmasligi uchun.

state prop — qo'shimcha ma'lumot uzatish

URL ko'rinmagan ma'lumotni keyingi sahifaga uzatish mumkin:

<Link
  to="/mahsulot/42"
  state={{ manbaSahifa: 'qidiruv' }}
>
  Mahsulotga o'tish
</Link>

Keyingi sahifada useLocation().state orqali olinadi:

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

function MahsulotDetali() {
  const { state } = useLocation();
  console.log(state?.manbaSahifa); // "qidiruv"
}

NavLink nima va qanday farqlanadi?

<NavLink> — <Link> ning kuchliroq versiyasi. U joriy URL va o'zining to manzilini solishtirib, mos kelsa avtomatik active class qo'shadi.

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

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

/mahsulotlar da turganda, brauzer DOM da shunday ko'rinadi:

<a href="/">Bosh sahifa</a>
<a href="/mahsulotlar" class="active">Mahsulotlar</a>  <!-- active qo'shildi -->
<a href="/haqida">Haqida</a>

CSS da faqat shu classni stilizatsiya qilsangiz yetadi:

nav a.active {
  color: #2563eb;
  font-weight: bold;
  border-bottom: 2px solid #2563eb;
}

NavLink — className funksiya sifatida

className prop ga funksiya uzatish mumkin. Funksiya { isActive } ob'ektini oladi:

<NavLink
  to="/mahsulotlar"
  className={({ isActive }) => isActive ? 'havola faol' : 'havola'}
>
  Mahsulotlar
</NavLink>

Bu Tailwind yoki CSS Modules bilan juda qulay:

<NavLink
  to="/mahsulotlar"
  className={({ isActive }) =>
    isActive
      ? 'px-4 py-2 rounded bg-blue-600 text-white'
      : 'px-4 py-2 rounded text-gray-600 hover:bg-gray-100'
  }
>
  Mahsulotlar
</NavLink>

NavLink — style funksiya sifatida

style prop ga ham funksiya uzatish mumkin:

<NavLink
  to="/mahsulotlar"
  style={({ isActive }) => ({
    color: isActive ? '#2563eb' : '#374151',
    fontWeight: isActive ? 'bold' : 'normal',
  })}
>
  Mahsulotlar
</NavLink>

NavLink — isPending holati

isPending — lazy loading bilan ishlatiladigan holat. Sahifa yuklanish jarayonida true bo'ladi.

<NavLink
  to="/mahsulotlar"
  className={({ isActive, isPending }) =>
    isPending ? 'yuklanmoqda' : isActive ? 'faol' : ''
  }
>
  Mahsulotlar
</NavLink>

Odatda bu kerak emas, lekin og'ir sahifalarda yuklash indikatori ko'rsatish uchun qulay.


end prop — aniq moslashish

<NavLink to="/"> muammo: / barcha URL ning boshida bo'ladi. Demak /mahsulotlar da ham "/" faol ko'rinadi.

{/* ❌ Muammo — "/" har doim active bo'ladi */}
<NavLink to="/">Bosh sahifa</NavLink>
<NavLink to="/mahsulotlar">Mahsulotlar</NavLink>

end prop bu muammoni hal qiladi — faqat URL aniq shu manzil bilan tugaganda faol bo'ladi:

{/* ✅ To'g'ri — faqat "/" da active */}
<NavLink to="/" end>Bosh sahifa</NavLink>
<NavLink to="/mahsulotlar">Mahsulotlar</NavLink>

To'liq navigatsiya misoli

// src/components/Nav.jsx
import { NavLink } from 'react-router-dom';
import styles from './Nav.module.css';

const havolalar = [
  { to: '/', label: 'Bosh sahifa', end: true },
  { to: '/mahsulotlar', label: 'Mahsulotlar' },
  { to: '/kategoriyalar', label: 'Kategoriyalar' },
  { to: '/haqida', label: 'Haqida' },
];

function Nav() {
  return (
    <nav className={styles.nav}>
      {havolalar.map(({ to, label, end }) => (
        <NavLink
          key={to}
          to={to}
          end={end}
          className={({ isActive }) =>
            isActive ? styles.havola + ' ' + styles.faol : styles.havola
          }
        >
          {label}
        </NavLink>
      ))}
    </nav>
  );
}

export default Nav;
/* src/components/Nav.module.css */
.nav {
  display: flex;
  gap: 8px;
  padding: 12px 24px;
  background: #f8fafc;
  border-bottom: 1px solid #e2e8f0;
}

.havola {
  padding: 6px 12px;
  border-radius: 6px;
  color: #475569;
  text-decoration: none;
  font-size: 14px;
}

.havola:hover {
  background: #e2e8f0;
}

.faol {
  background: #2563eb;
  color: white;
}

.faol:hover {
  background: #1d4ed8;
}

Link va NavLink — qachon qaysi?

Holat Ishlatish
Oddiy havola — sahifaga o'tish <Link>
Navigatsiya menyusi <NavLink>
Tugma ko'rinishidagi havola <Link>
Breadcrumb <NavLink>
Footer havolalari <Link>

Qoida sodda: agar havolaning "faol" holati vizual ko'rsatilishi kerak bo'lsa — <NavLink>. Boshqa barcha holatlarda — <Link>.


Tez-tez uchraydigan xatolar

1. <a href> ni unutib ishlatish

// ❌ Xato — sahifa yangilanadi, state yo'qoladi
<a href="/mahsulotlar">Mahsulotlar</a>

// ✅ To'g'ri
<Link to="/mahsulotlar">Mahsulotlar</Link>

Sababi: <a href> brauzerga to'liq sahifa yangilashni buyuradi. Hamma React holati (savatcha, forma, scroll) yo'qoladi. <Link> esa faqat komponentni almashtiradi.


2. Bosh sahifada end prop ni unutish

// ❌ Xato — "/" har doim active ko'rinadi
<NavLink to="/">Bosh sahifa</NavLink>
<NavLink to="/mahsulotlar">Mahsulotlar</NavLink>

// ✅ To'g'ri
<NavLink to="/" end>Bosh sahifa</NavLink>
<NavLink to="/mahsulotlar">Mahsulotlar</NavLink>

Sababi: /mahsulotlar URL si / bilan boshlanadi. end prop bo'lmasa, NavLink "men ham mos kelaman" deb active class oladi. end bilan faqat URL aniq / bo'lganda faol bo'ladi.


3. className funksiyasini noto'g'ri yozish

// ❌ Xato — destrukturizatsiya yo'q
<NavLink className={(isActive) => isActive ? 'faol' : ''}>
  ...
</NavLink>

// ✅ To'g'ri — ob'ektdan destrukturizatsiya
<NavLink className={({ isActive }) => isActive ? 'faol' : ''}>
  ...
</NavLink>

Sababi: React Router funksiyaga { isActive, isPending } ob'ektini uzatadi, to'g'ridan-to'g'ri boolean emas. Destrukturizatsiya qilmasangiz, isActive har doim undefined bo'ladi va shart noto'g'ri ishlaydi.


4. NavLink ichidagi matnni faqat string qilish

// Muammo — NavLink faqat string farzand kutmaydi
<NavLink to="/profil">
  <img src={avatar} alt="Profil" />
  <span>Profil</span>
</NavLink>

Bu ishlaydi — NavLink ichida istalgan JSX bo'lishi mumkin. Lekin faol holat uchun style yoki className funksiyasidan foydalaning, ichki elementlarga alohida class qo'shishga hojat yo'q.


Xulosa

  • <Link> — <a> o'rniga, sahifani yangilamaydi
  • <NavLink> — faol holat uchun, active class avtomatik qo'shiladi
  • className={({ isActive }) => ...} — shartli class qo'shish
  • style={({ isActive }) => ...} — shartli stil berish
  • end — bosh sahifa ("/") uchun aniq moslashish
  • replace — tarixga qo'shmasdan URL ni almashtirish
  • state — URL ko'rinmagan ma'lumot uzatish

Keyingi dars: 42-dars: useNavigate — dasturiy navigatsiya