Next.js / Link ба навигаци

Link ба навигаци

Хуудсуудын хооронд шилжихэд HTML-н <a> тэгийг ашиглаж болно — гэхдээ Next.js-д <Link> component ашиглах нь зөв арга. Яагаад гэдгийг энэ хичээлд ойлгоно.

тэгийн асуудал

Ердийн <a> тэг дарах бүрт хөтөч бүх хуудсыг дахин татаж, JS-г дахин ачаалдаг:

tsx
// ❌ Буруу — бүтэн хуудас шинэчлэгдэнэ
export default function Navbar() {
  return (
    <nav>
      <a href="/">Нүүр</a>
      <a href="/courses">Сургалтууд</a>
    </nav>
  );
}

Энэ нь аппаа удаашруулж, хэрэглэгчийн туршлагыг муутгана.

component

next/link<Link> component нь хуудас дахин ачаалалгүйгээр шилжилт хийдэг — client-side navigation:

tsx
// ✅ Зөв — зөвхөн шаардлагатай хэсэг шинэчлэгдэнэ
import Link from "next/link";

export default function Navbar() {
  return (
    <nav>
      <Link href="/">Нүүр</Link>
      <Link href="/courses">Сургалтууд</Link>
      <Link href="/profile">Профайл</Link>
    </nav>
  );
}

<Link> нь нэмэлт давуу талтай: хэрэглэгч hover хийхэд тухайн хуудсыг урьдчилан татаж эхэлдэг — энэ нь prefetching гэж нэрлэгддэг. Иймд хуудас lightning fast мэт санагдана.

Dynamic хаяг үүсгэх

Dynamic route руу шилжихэд тэмдэгт мөрийг нийлүүлж href-д дамжуулна:

tsx
import Link from "next/link";

interface Course {
  slug: string;
  title: string;
}

export default function CourseList({ courses }: { courses: Course[] }) {
  return (
    <ul>
      {courses.map((course) => (
        <li key={course.slug}>
          <Link href={`/courses/${course.slug}`}>{course.title}</Link>
        </li>
      ))}
    </ul>
  );
}

Идэвхтэй холбоос тодруулах

Тухайн үед байгаа хуудасны холбоосыг тодруулахад usePathname hook ашиглана. Hook ашиглаж байгаа тул энэ component 'use client' байх ёстой:

tsx
// components/nav/Navbar.tsx
"use client";

import Link from "next/link";
import { usePathname } from "next/navigation";

const navItems = [
  { href: "/", label: "Нүүр" },
  { href: "/courses", label: "Сургалтууд" },
  { href: "/projects", label: "Төслүүд" },
  { href: "/profile", label: "Профайл" },
];

export default function Navbar() {
  const pathname = usePathname();

  return (
    <nav className="flex gap-4 p-4">
      {navItems.map((item) => {
        const isActive = pathname === item.href;
        return (
          <Link
            key={item.href}
            href={item.href}
            className={isActive ? "text-white font-bold" : "text-slate-400"}
          >
            {item.label}
          </Link>
        );
      })}
    </nav>
  );
}

Программаар шилжих — useRouter

Товч дарах, маягт илгээх зэрэг үйлдлийн дараа программаар хуудас солих шаардлага гардаг. Энэ тохиолдолд useRouter hook ашиглана:

tsx
"use client";

import { useRouter } from "next/navigation";

export default function LoginForm() {
  const router = useRouter();

  async function handleLogin() {
    // ... нэвтрэлтийн логик ...

    // Амжилтай нэвтэрсний дараа профайл руу шилжих
    router.push("/profile");
  }

  return <button onClick={handleLogin}>Нэвтрэх</button>;
}

| Метод | Үйлдэл | | -------------------------- | ------------------------------ | | router.push('/profile') | Шинэ хуудас нэмж шилжинэ | | router.replace('/login') | Одоогийн хуудсыг солиж шилжинэ | | router.back() | Өмнөх хуудас руу буцна | | router.refresh() | Хуудсыг сервераас дахин татна |

searchParams — URL-н query

/courses?category=free гэх мэт query parameter-г searchParams prop-оор авна:

tsx
// app/courses/page.tsx
interface Props {
  searchParams: Promise<{ category?: string }>;
}

export default async function CoursesPage({ searchParams }: Props) {
  const { category } = await searchParams;

  return (
    <main>
      <p>Категори: {category ?? "бүгд"}</p>
    </main>
  );
}

Дараагийн хичээлд:

Server Component-г гүнзгий судална. Сервер дээр өгөгдлийн сангаас шууд өгөгдөл татах, bundle хэмжээг хэрхэн багасгах тухай ойлгоно.