You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS中基于JSON数据实现商品列表跳转详情页的技术咨询

Alright, let's break this down into simple, actionable steps to get your product detail navigation working properly. You're already halfway there with your ProductDetail.jsx file—here's what to do next:

Step 1: Configure React Router for Detail Pages

First, confirm you have react-router-dom installed (it looks like you're already using <Link> so you probably do, but double-check with npm install react-router-dom if needed). Next, set up a route in your main routing file (usually App.js or Routes.jsx) that maps to your ProductDetail component, including the product ID as a URL parameter:

// Import necessary components at the top of your main routing file
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Products from './path/to/Products';
import ProductDetail from './path/to/ProductDetail';

function App() {
  return (
    <Router>
      <Routes>
        {/* Existing route for your product list */}
        <Route path="/" element={<Products />} />
        {/* New route for product detail, with dynamic :id parameter */}
        <Route path="/product/:id" element={<ProductDetail />} />
      </Routes>
    </Router>
  );
}

export default App;

In your Products.jsx file, first import Link from react-router-dom (if you haven't already), then modify the "View Details" button to use this component and pass the product's ID in the URL:

// Add this import at the top of Products.jsx
import { Link } from 'react-router-dom';

// ... inside the ProductList component's render method ...
// Replace your existing details Button with this:
<Link to={`/product/${this.props.product.id}`} className='btn btn-primary'>
  {details}
</Link>

This will make each "View Details" button navigate to a unique URL like /product/1 for your first product, which matches the route we set up earlier.

Step 3: Fetch & Display Product Details in ProductDetail.jsx

Now, in your ProductDetail.jsx component, you need to grab the product ID from the URL, find the matching product in your JSON data, and render its details. Here's a complete example:

import React, { Component } from 'react';
import { useParams } from 'react-router-dom';
import Request from 'your-request-library'; // Use the same request library as in Products.jsx

// Class component wrapped to access route params (since useParams is a hook)
class ProductDetail extends Component {
  constructor(props) {
    super(props);
    this.state = { product: null, loading: true };
  }

  componentDidMount() {
    const { id } = this.props;
    Request.get('./products.json')
      .then((res) => {
        // Find the product with the matching ID (convert id to number since URL params are strings)
        const matchedProduct = res.body.data.find(item => item.id === parseInt(id));
        this.setState({ product: matchedProduct, loading: false });
      })
      .catch(err => {
        alert(err);
        this.setState({ loading: false });
      });
  }

  render() {
    if (this.state.loading) return <div className="text-center mt-5">Loading product details...</div>;
    if (!this.state.product) return <div className="text-center mt-5">Product not found!</div>;

    const { title, img, des, rs, detailPage } = this.state.product;
    const { productDetail, qty, size, color } = detailPage[0];

    return (
      <div className="container mt-4">
        <div className="row">
          <div className="col-md-6">
            <img src={img} alt={title} className="img-fluid rounded" />
          </div>
          <div className="col-md-6">
            <h2>{title}</h2>
            <p className="text-muted">{des}</p>
            <h4 className="text-danger">Rs : {rs} /-</h4>
            <hr />
            <p><strong>Product Info:</strong> {productDetail}</p>
            <p><strong>Available Stock:</strong> {qty}</p>
            <p><strong>Sizes:</strong> {size}</p>
            <p><strong>Colors:</strong> {color}</p>
            <button className='btn btn-danger mt-3'>Add to Cart</button>
          </div>
        </div>
      </div>
    );
  }
}

// Wrap the class component to access route parameters
export default function WrappedProductDetail() {
  const params = useParams();
  return <ProductDetail id={params.id} />;
}

Optional: Reuse Data to Avoid Duplicate API Calls

If you want to skip fetching products.json twice, lift the state up to a parent component (like App.js) and pass the product data down to both Products and ProductDetail:

  1. Update App.js to hold the product data:
class App extends Component {
  constructor(props) {
    super(props);
    this.state = { products: [], loading: true };
  }

  componentDidMount() {
    Request.get('./products.json')
      .then((res) => {
        this.setState({ products: res.body.data, loading: false });
      })
      .catch(err => alert(err));
  }

  render() {
    if (this.state.loading) return <div className="text-center mt-5">Loading...</div>;
    return (
      <Router>
        <Routes>
          <Route path="/" element={<Products products={this.state.products} />} />
          <Route path="/product/:id" element={<ProductDetail products={this.state.products} />} />
        </Routes>
      </Router>
    );
  }
}
  1. Modify Products.jsx to use passed data instead of fetching:
// Update ProductsC component to accept products from props
class ProductsC extends React.Component {
  render() {
    return (
      <Row className="products-container">
        <Col sm={12}>
          { this.props.products.map( (product, index) => (
            <ProductList key={index} product={product} />
          )) }
        </Col>
      </Row>
    )
  }
}

// Update the parent Products component to pass props down
export default class Products extends React.Component {
  render() {
    return (
      <Grid>
        <Row>
          <Col sm={12} className="text-center">
            <h2>MEN'S STYLES</h2>
            <p>To Make a Lasting Impression</p>
          </Col>
        </Row>
        <ProductsC products={this.props.products} />
      </Grid>
    );
  }
}
  1. Update ProductDetail to use passed data:
// In ProductDetail's componentDidMount
componentDidMount() {
  const { id, products } = this.props;
  const matchedProduct = products.find(item => item.id === parseInt(id));
  this.setState({ product: matchedProduct, loading: false });
}

That's all! You should now have fully functional navigation from your product list to individual detail pages. Let me know if you hit any roadblocks.

内容的提问来源于stack exchange,提问作者Developer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:58:13