التنقل بين الصفحات

في الفصل السابق، قمت بإنشاء تخطيط لوحة التحكم والصفحات. الآن، دعونا نضيف بعض الروابط للسماح للمستخدمين بالتنقل بين مسارات لوحة التحكم.

لماذا نُحسّن التنقل؟

لربط الصفحات معًا، تقليديًا نستخدم عنصر <a> في HTML. حاليًا، روابط الشريط الجانبي تستخدم عناصر <a>، لكن لاحظ ما يحدث عند التنقل بين الصفحات الرئيسية والفواتير والعملاء في متصفحك.

هل لاحظت ذلك؟

يحدث تحديث كامل للصفحة في كل مرة تنتقل بين الصفحات!

في Next.js، يمكنك استخدام مكون <Link /> لربط الصفحات داخل تطبيقك. <Link> يسمح لك بالتنقل من جانب العميل (client-side navigation) باستخدام JavaScript.

لاستخدام مكون <Link />، افتح ملف /app/ui/dashboard/nav-links.tsx، واستورد مكون Link من next/link. ثم استبدل وسم <a> بـ <Link>:

/app/ui/dashboard/nav-links.tsx
import {
  UserGroupIcon,
  HomeIcon,
  DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
 
// ...
 
export default function NavLinks() {
  return (
    <>
      {links.map((link) => {
        const LinkIcon = link.icon;
        return (
          <Link
            key={link.name}
            href={link.href}
            className="flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3"
          >
            <LinkIcon className="w-6" />
            <p className="hidden md:block">{link.name}</p>
          </Link>
        );
      })}
    </>
  );
}

كما ترى، مكون Link مشابه لاستخدام وسم <a>، ولكن بدلاً من <a href="…">، تستخدم <Link href="…">.

احفظ التغييرات وتحقق مما إذا كانت تعمل على localhost الخاص بك. يجب أن تكون الآن قادرًا على التنقل بين الصفحات دون حدوث تحديث كامل للصفحة. على الرغم من أن أجزاء من تطبيقك يتم عرضها على الخادم، إلا أنه لا يوجد تحديث كامل للصفحة، مما يجعلها تبدو كتطبيق ويب أصلي. لماذا يحدث ذلك؟

تقسيم الشفرة تلقائيًا وجلبها مسبقًا

لتحسين تجربة التنقل، يقوم Next.js تلقائيًا بتقسيم شفرة تطبيقك حسب مقاطع المسار. هذا يختلف عن تطبيقات React التقليدية ذات الصفحة الواحدة (SPA)، حيث يقوم المتصفح بتحميل كل شفرة التطبيق عند تحميل الصفحة الأولى.

تقسيم الشفرة حسب المسارات يعني أن الصفحات تصبح معزولة. إذا حدث خطأ في صفحة معينة، سيستمر بقية التطبيق في العمل. كما أن هذا يعني كمية أقل من الشفرة للمتصفح لتحليلها، مما يجعل تطبيقك أسرع.

علاوة على ذلك، في بيئة الإنتاج، عندما تظهر مكونات <Link> في نافذة عرض المتصفح، يقوم Next.js تلقائيًا بجلب شفرة المسار المرتبط مسبقًا في الخلفية. بحلول الوقت الذي ينقر فيه المستخدم على الرابط، ستكون شفرة الصفحة الهدف قد تم تحميلها بالفعل في الخلفية، وهذا ما يجعل الانتقال بين الصفحات شبه فوري!

تعلم المزيد حول كيفية عمل التنقل.

نمط: عرض الروابط النشطة

نمط واجهة مستخدم شائع هو عرض رابط نشط للإشارة إلى الصفحة الحالية للمستخدم. للقيام بذلك، تحتاج إلى الحصول على المسار الحالي للمستخدم من عنوان URL. يوفر Next.js خطافًا يسمى usePathname() يمكنك استخدامه للتحقق من المسار وتطبيق هذا النمط.

بما أن usePathname() هو خطاف React، ستحتاج إلى تحويل ملف nav-links.tsx إلى مكون عميل. أضف توجيه "use client" الخاص بـ React إلى أعلى الملف، ثم استورد usePathname() من next/navigation:

/app/ui/dashboard/nav-links.tsx
'use client';
 
import {
  UserGroupIcon,
  HomeIcon,
  DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
 
// ...

بعد ذلك، قم بتعيين المسار إلى متغير يسمى pathname داخل مكون <NavLinks /> الخاص بك:

/app/ui/dashboard/nav-links.tsx
export default function NavLinks() {
  const pathname = usePathname();
  // ...
}

ملاحظة: nav-links.tsx ليس ملفًا خاصًا بـ Next.js - يمكن تسميته بأي اسم تريده. إذا قمت بتغيير اسمه، تأكد من تحديث عبارات الاستيراد وفقًا لذلك.

يمكنك استخدام مكتبة clsx التي تم تقديمها في فصل تنسيق CSS لتطبيق أسماء الفئات بشكل مشروط عندما يكون الرابط نشطًا. عندما يتطابق link.href مع pathname، يجب عرض الرابط بنص أزرق وخلفية زرقاء فاتحة.

إليك الشفرة النهائية لملف nav-links.tsx:

/app/ui/dashboard/nav-links.tsx
'use client';
 
import {
  UserGroupIcon,
  HomeIcon,
  DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import clsx from 'clsx';
 
// ...
 
export default function NavLinks() {
  const pathname = usePathname();
 
  return (
    <>
      {links.map((link) => {
        const LinkIcon = link.icon;
        return (
          <Link
            key={link.name}
            href={link.href}
            className={clsx(
              'flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3',
              {
                'bg-sky-100 text-blue-600': pathname === link.href,
              },
            )}
          >
            <LinkIcon className="w-6" />
            <p className="hidden md:block">{link.name}</p>
          </Link>
        );
      })}
    </>
  );
}

احفظ وتفقد localhost الخاص بك. يجب أن ترى الآن الرابط النشط مميزًا باللون الأزرق.