شارك المقالة

شرح استخدام react-router-dom في React مع تطبيق عملي على عرض المنتجات وتفاصيلها

عند بناء تطبيق باستخدام React، نحتاج إلى نظام تنقل يسمح بالانتقال بين الصفحات بدون إعادة تحميل الصفحة. هنا تأتي مكتبة react-router-dom التي تعتبر الحل الأساسي لإدارة التنقل داخل تطبيقات React الحديثة.

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


الصفحة الأولى: main.jsx


import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.bundle.min.js'
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'
import App from './App.jsx'
import './index.css'

createRoot(document.getElementById('root')).render(




,
)

شرح الصفحة

هذه الصفحة هي نقطة تشغيل التطبيق. تم استخدام BrowserRouter لتفعيل نظام التنقل داخل التطبيق، حيث يسمح باستخدام الروابط والمسارات بدون إعادة تحميل الصفحة.

كما تم استيراد Bootstrap لتنسيق الواجهة، واستخدام StrictMode للمساعدة في اكتشاف الأخطاء أثناء التطوير.


الصفحة الثانية: App.jsx


import { Route, Routes } from 'react-router-dom';
import Navbar from './componants/componants/Navbar';
import ProductList from './componants/componants/ProductList';
import Slider from './componants/componants/Slider';
import ProductDetail from './componants/ProductDetail';

function App() {
return (
<>


```
  <Routes>

    <Route
      path="/"
      element={
        <>
          <Slider />
          <ProductList />
        </>
      }
    />

    <Route
      path="/products/:prodId"
      element={<ProductDetail />}
    />

  </Routes>

</>
```

)
}

export default App;

شرح الصفحة

هذه الصفحة مسؤولة عن تعريف المسارات داخل التطبيق. تم استخدام Routes لتحديد أي مكون يتم عرضه حسب الرابط.

  • المسار / يعرض الصفحة الرئيسية (Slider + ProductList)
  • المسار /products/:prodId يعرض صفحة تفاصيل المنتج

تم استخدام المسار الديناميكي :prodId لتمكين عرض أي منتج باستخدام نفس الصفحة.

كما أن Navbar تم وضعه خارج Routes لأنه يظهر في جميع الصفحات.


الصفحة الثالثة: ProductDetail.jsx


import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import ProductItem from "./componants/Product";
import { useNavigate } from "react-router-dom";

function ProductDetail(props) {
const prodId = useParams().prodId;
const baseURL = "[https://fakestoreapi.com](https://fakestoreapi.com/)";
const [product, setProduct] = useState({});
const navigate = useNavigate();

```
useEffect(() => {
    fetch(`${baseURL}/products/${prodId}`)
        .then((res) => res.json())
        .then((data) => setProduct(data));
}, []);

return (
    <div>
        <div className="container mt-5">

            <h1>Product Detail</h1>

            <ProductItem
              product={product}
              showButton={false}
              allData={true}
            />

            <button
              className="btn btn-primary mb-3 w-100"
              onClick={() => navigate(-1)}
            >
              Go Back
            </button>

        </div>
    </div>
)
```

}

export default ProductDetail;

شرح الصفحة

هذه الصفحة مسؤولة عن عرض تفاصيل منتج واحد. يتم قراءة رقم المنتج من الرابط باستخدام useParams، ثم يتم جلب بيانات المنتج من API.

بعد جلب البيانات، يتم عرضها باستخدام مكون ProductItem.

تم أيضًا استخدام useNavigate لإضافة زر “Go Back” الذي يسمح للمستخدم بالرجوع إلى الصفحة السابقة بسهولة.


الصفحة الرابعة: ProductItem.jsx


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

function ProductItem({ product, showButton = true, allData = false }) {
return (
``` <img src={product?.image} style={{ height: "300px", objectFit: "contain" }} className="card-img-top p-5" alt={product?.title ? product.title : "Loading..."} /> <div className="card-body d-flex flex-column justify-content-between"> <h5 className="card-title"> {product?.title ? allData ? product.title : product.title.substring(0, 15) + "..." : "Loading..."} </h5> <p className="card-text"> {product?.description ? allData ? product.description : product.description.substring(0, 100) + "..." : "Loading..."} </p> {showButton && ( <Link to={`/products/${product.id}`} className="btn btn-primary"> View Details </Link> )} </div> </div> ``` ); } export default ProductItem;

شرح الصفحة

هذا المكون مسؤول عن عرض المنتج داخل بطاقة. تم تصميمه ليكون قابل لإعادة الاستخدام.

  • في الصفحة الرئيسية: يعرض بيانات مختصرة + زر انتقال
  • في صفحة التفاصيل: يعرض البيانات كاملة بدون زر

تم استخدام Link للتنقل بين الصفحات بدون إعادة تحميل الصفحة.


مميزات التطبيق

  • تنقل سريع بدون إعادة تحميل الصفحة
  • استخدام مسارات ديناميكية
  • إعادة استخدام المكونات
  • فصل منطق البيانات عن العرض
  • تجربة مستخدم سلسة

ملاحظات

  • يفضل إضافة حالة تحميل (Loading)
  • يفضل التعامل مع أخطاء API
  • إضافة prodId داخل useEffect

الخلاصة

باستخدام react-router-dom يمكنك بناء تطبيق React احترافي يحتوي على صفحات متعددة وتنقل سلس. هذا المثال يوضح كيفية الربط بين الصفحات، واستخدام المسارات الديناميكية، وعرض البيانات بطريقة منظمة.




لمزيد من المقالات : MVI Architecture Pattern في Flutter: تحكم دقيق في تدفق البيانات وتجربة مستخدم تفاعلية
شاهد أيضًا
مقالات ذات صلة

🚫 مانع الإعلانات مفعل

يجب إيقاف مانع الإعلانات لاستكمال تصفح الموقع