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

MERN项目拉取单商品报CastError: _id为undefined 如何解决

问题根因

你的报错核心是 ProductDetails 组件没有拿到路由传递的id参数,导致match.params.id为undefined,请求后端时把undefined作为id传入,Mongoose尝试将非ObjectId格式的undefined转换为_id类型时抛出错误。

分版本解决方案

情况1:使用React Router v6(目前主流版本)

v6已经移除了组件props中的match、history等对象,需要用内置的useParams钩子取参数,修改ProductDetails.jsx代码:

// 首先导入useParams
import React, {useState, useEffect} from 'react';
import axios from "axios";
import Rating from "../components/Rating";
import {Row, Col, ListGroup, Button, Image, ListGroupItem} from "react-bootstrap";
import {Link, useParams} from "react-router-dom"; // 新增导入useParams

const ProductDetails = () => { // 去掉match参数解构
    const {id} = useParams(); // 调用useParams取路由id参数
    const [product, setProduct] = useState({}) // 初始值改空对象,不要用数组,避免后续取属性报错
    useEffect(() => {
        const fetchProduct = async () => {
            const {data} = await axios.get(`/api/products/${id}`) // 替换为useParams拿到的id
            setProduct(data);
        }
        fetchProduct();
    },[id]); // 依赖改为id
    // 渲染部分建议给属性加可选链,避免数据加载完成前报错,比如product?.name、product?.rating
    return (
        <div>
            <Link to="/" className="btn btn-light"><i className="fas fa-arrow-left"></i> &nbsp;GO BACK</Link>
            <Row>
                <Col md={6}>
                    <Image src={product?.image} alt={product?.name} fluid/>
                </Col>
                <Col md={3}>
                    <ListGroup variant="flush">
                        <ListGroupItem>
                            <h3>{product?.name}</h3>
                        </ListGroupItem>
                        <ListGroupItem>
                            <Rating value={product?.rating} text={`${product?.numReviews} reviews`}></Rating>
                        </ListGroupItem>
                        <ListGroupItem>
                            Price: ${product?.price}
                        </ListGroupItem>
                        <ListGroupItem>
                            {product?.description}
                        </ListGroupItem>
                    </ListGroup>
                </Col>
                <Col md={3}>
                    <ListGroupItem>
                        <Row>
                            <Col>Status: </Col>
                            <Col>{product?.countInStock > 0 ? 'In stock' : 'Out of stock'} </Col>
                        </Row>
                    </ListGroupItem>
                    <ListGroupItem>
                        <Button className="btn-block" type="button">Add to cart</Button>
                    </ListGroupItem>
                </Col>
            </Row>
        </div>
    );
}

export default ProductDetails;

同时检查你的路由配置,确保路径有:id占位符:

<Route path="/products/:id" element={<ProductDetails />} />

情况2:使用React Router v5

问题出在路由配置没有把props传递给组件,检查你的路由写法:

  • 如果用component属性:确保写法为 <Route path="/products/:id" component={ProductDetails} />,会自动注入match参数
  • 如果用render属性:需要手动透传props:<Route path="/products/:id" render={(props) => <ProductDetails {...props} />} />

额外检查项

检查商品列表页跳转详情的Link组件写法,确保传入的是MongoDB的_id字段,不是自定义的id:

<Link to={`/products/${product._id}`}>查看商品详情</Link>

内容的提问来源于stack exchange,提问作者ZaIn Ul AbiDeen Sān

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 16:39:03