Skip to content

arribion-link/e-commerce-beginner-dynamic-simulation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

1. Install the exact version you need

npm create vite@latest my-shop -- --template react
cd my-shop
npm i react-router-dom@6
npm i

2. Full file tree (copy‑paste)

src/
├─ main.jsx          ← entry point (creates root + router)
├─ App.jsx           ← UI layout
├─ data/
│   └─ products.js
└─ pages/
    ├─ Home.jsx
    └─ ProductDetail.jsx

3. src/main.jsxRouter root

// src/main.jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App.jsx';
import './index.css';   // optional

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
);

4. src/App.jsx – Layout + Routes

// src/App.jsx
import { Routes, Route } from 'react-router-dom';
import Home from './pages/Home.jsx';
import ProductDetail from './pages/ProductDetail.jsx';

export default function App() {
  return (
    <div style={{ padding: '2rem', fontFamily: 'system-ui, sans-serif' }}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/products/:id" element={<ProductDetail />} />
      </Routes>
    </div>
  );
}

5. src/data/products.js

// src/data/products.js
const products = [
  { id: '1', name: 'Eco Water Bottle', price: 15.99, description: 'Reusable and BPA‑free.' },
  { id: '2', name: 'Wireless Headphones', price: 89.99, description: 'Noise‑cancelling, 30‑hr battery.' },
  { id: '3', name: 'Yoga Mat', price: 25.5, description: 'Non‑slip, eco‑friendly.' },
];

export default products;

6. src/pages/Home.jsx

// src/pages/Home.jsx
import { Link } from 'react-router-dom';
import products from '../data/products';

export default function Home() {
  return (
    <>
      <h1>Our Products</h1>
      <div style={{ display: 'grid', gap: '1rem', gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))' }}>
        {products.map((p) => (
          <Link
            key={p.id}
            to={`/products/${p.id}`}
            style={{ textDecoration: 'none', color: 'inherit' }}
          >
            <div
              style={{
                border: '1px solid #ddd',
                borderRadius: '8px',
                padding: '1rem',
                textAlign: 'center',
                cursor: 'pointer',
                transition: 'transform .2s',
              }}
              onMouseEnter={(e) => (e.currentTarget.style.transform = 'scale(1.03)')}
              onMouseLeave={(e) => (e.currentTarget.style.transform = '')}
            >
              <h3 style={{ margin: '0 0 .5rem' }}>{p.name}</h3>
              <p style={{ margin: 0, fontWeight: 'bold' }}>${p.price}</p>
            </div>
          </Link>
        ))}
      </div>
    </>
  );
}

7. src/pages/ProductDetail.jsx

// src/pages/ProductDetail.jsx
import { useParams, Link } from 'react-router-dom';
import products from '../data/products';

export default function ProductDetail() {
  const { id } = useParams();
  const product = products.find((p) => p.id === id);

  if (!product) {
    return (
      <div style={{ textAlign: 'center', marginTop: '2rem' }}>
        <h2>Product not found</h2>
        <Link to="/">← Back to Home</Link>
      </div>
    );
  }

  return (
    <div style={{ maxWidth: '600px', margin: '2rem auto' }}>
      <Link to="/" style={{ display: 'inline-block', marginBottom: '1rem' }}>
        ← Back to Home
      </Link>
      <h1>{product.name}</h1>
      <p>
        <strong>Price:</strong> ${product.price}
      </p>
      <p>
        <strong>Description:</strong> {product.description}
      </p>
    </div>
  );
}

8. Run

npm run dev

Open http://localhost:5173 → click any product → you’ll land on /products/1, /products/2, etc. and see the full detail.


Why the original “didn’t work”

Symptom Root cause Fix
Clicking a card reloads the page and shows “Product not found” <Link> was wrapped around the card, but the card itself contained a <div> that stopped the event (or you used <a href>). Keep the entire card inside a single <Link> (as shown).
useParams() returns undefined Router not mounted at the top level. Wrap the app with <BrowserRouter> in main.jsx.
products array not found Wrong import path (../data/products vs ../data/products.js). Use the exact relative path or add a .js extension if needed.

TL;DR – One‑line checklist

  1. react-router-dom@6 installed.
  2. <BrowserRouter> around <App /> in main.jsx.
  3. <Link to="/products/${id}"> wraps the whole card.
  4. useParams() + products.find(p => p.id === id) in ProductDetail.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published