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> 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
相关产品推荐
相关产品推荐

