أساسيات التوجيه والتنقل وبناء الصفحات عبر React Router
| المكون الأساسي | وظيفته البرمجية في React Router | الأثر على متصفح المستخدم (UX) |
|---|---|---|
| BrowserRouter | المكون الأب الذي يغلف التطبيق ويفعل نظام إدارة السجل (History API) | ربط روابط الـ URL الداخلية بمسارات التطبيق دون الحاجة لإعادة تحميل الصفحة |
| Routes & Route | تحديد قائمة المسارات وتعيين كل مسار بـ Path والمكون المخصص له | عرض المكون المناسب فوراً بمجرد مطابقة الرابط المطلوب |
| Link | المكون البديل عن وسم الـ a التقليدي للتنقل الداخلي | تغيير رابط الصفحة بدون إجراء Refresh كلي للمتصفح (Single Page Application) |
| NavLink | وسم تنقل ذكي يتتبع الرابط الحالي للتمييز البصري | إضافة فئة نشطة (Active Class) تلقائياً لتحديد الصفحة الحالية في قوائم التنقل |
تعتمد تطبيقات ريأكت على مفهوم تطبيق الصفحة الواحدة (Single Page Application - SPA)، حيث لا يتم جلب ملف HTML جديد عند التنقل بين الصفحات، بل يتم تبديل المكونات المعروضة ديناميكياً بحسب رابط الـ URL.
لتحقيق ذلك بأسلوب احترافي، نستخدم المكتبة القياسية المعتمدة: react-router-dom.
نغلف التطبيق بالكامل بـ BrowserRouter ثم نحدد شجرة المسارات داخل Routes:
| 1 | import { BrowserRouter, Routes, Route } from 'react-router-dom'; |
| 2 | |
| 3 | function App() { |
| 4 | return ( |
| 5 | <BrowserRouter> |
| 6 | <Routes> |
| 7 | {/* تحديد الصفحة الرئيسية وصفحة الكورسات */} |
| 8 | <Route path="/" element={<HomePage />} /> |
| 9 | <Route path="/courses" element={<CoursesPage />} /> |
| 10 | |
| 11 | {/* صفحة 404 للمسارات غير الموجودة */} |
| 12 | <Route path="*" element={<NotFoundPage />} /> |
| 13 | </Routes> |
| 14 | </BrowserRouter> |
| 15 | ); |
| 16 | } |
استخدام وسم <a> العادي يتسبب في إعادة جلب الصفحة بالكامل (Full Page Reload) مما يمرر أداء الـ SPA. البديل هو استخدام <Link>:
| 1 | // تسبب إعادة تحميل كاملة للمتصفح وتفقد الـ State |
| 2 | <a href="/courses">الكورسات</a> |
| 1 | import { Link } from 'react-router-dom'; |
| 2 | |
| 3 | // تنقل لحظي بدون إعادة تحميل الصفحة |
| 4 | <Link to="/courses">تصفح الكورسات</Link> |
عند بناء قائمة التنقل (Navbar)، نحتاج لمعرفة الصفحة الحالية لإضافة تنسيق تمييزي (مثل لون مختلف تحت الزر):
| 1 | import { NavLink } from 'react-router-dom'; |
| 2 | |
| 3 | function Navbar() { |
| 4 | return ( |
| 5 | <nav> |
| 6 | {/* يحصل على isActive تلقائياً إذا كان الرابط يطابق الصفحة الحالية */} |
| 7 | <NavLink |
| 8 | to="/courses" |
| 9 | className={({ isActive }) => (isActive ? 'active-link' : '')} |
| 10 | > |
| 11 | الكورسات |
| 12 | </NavLink> |
| 13 | </nav> |
| 14 | ); |
| 15 | } |
⚠️ تحذير
تجنب وضع الـ BrowserRouter داخل مكونات فرعية!
الخطأ الشائع هو وضع <BrowserRouter> داخل المكون المخصص للـ Navbar أو داخل صفحة معينة.
يجب أن تكون هناك نسخة واحدة فقط من BrowserRouter وتغلف أعلى مستوى شجري في تطبيقك (يفضل داخل main.jsx أو App.jsx).