React电商网站商品详情页点击空白,出现ReferenceError错误求助
问题修复方案
错误根源分析
- 变量初始化顺序错误:
useEffect中第一行setProductData(productData);调用了尚未初始化的变量,且该productData状态变量在组件中完全未被使用,属于冗余代码,直接触发ReferenceError。 - 类型不匹配:
useParams()获取的id是字符串类型,而数据文件中商品id是数字,直接用item.id === id无法匹配到目标商品,导致product始终为空对象,渲染时访问属性会引发错误。 - 依赖数组缺失:
useEffect依赖数组为空,当路由参数id变化时不会重新执行数据筛选,切换商品时无法更新页面内容。
修改后的商品详情页(Product)代码
import React, { useState, useEffect } from "react"; import { Link, useParams } from "react-router-dom"; import Marquee from "react-fast-marquee"; import { useDispatch } from "react-redux"; import { addCart } from "../redux/action"; import data from "../components/data.json"; import { Footer, Navbar } from "../components"; const Product = () => { const { id } = useParams(); const [product, setProduct] = useState(null); const [similarProducts, setSimilarProducts] = useState([]); const dispatch = useDispatch(); useEffect(() => { // 将路由id转为数字,匹配数据中的id类型 const targetId = Number(id); // 筛选目标商品 const targetProduct = data.find(item => item.id === targetId); if (targetProduct) { setProduct(targetProduct); // 筛选同分类相似商品 const similarData = data.filter(item => item.category === targetProduct.category); setSimilarProducts(similarData); } }, [id]); // 添加id到依赖数组,路由变化时重新执行 const addProduct = (product) => { dispatch(addCart(product)); }; const ShowProduct = () => { // 当product为空时显示加载提示,避免报错 if (!product) { return <div className="container my-5 py-2 text-center">加载中...</div>; } return ( <> <div className="container my-5 py-2"> <div className="row"> <div className="col-md-6 col-sm-12 py-3"> <img className="img-fluid" src={product.image} alt={product.title} width="400" height="400" /> </div> <div className="col-md-6 py-5"> <h4 className="text-uppercase text-muted">{product.category}</h4> <h1 className="display-5">{product.title}</h1> <h3 className="display-6 my-4">${product.price}</h3> <p className="lead">{product.description}</p> <button className="btn btn-outline-dark" onClick={() => addProduct(product)} > Add to Cart </button> <Link to="/cart" className="btn btn-dark mx-3"> Go to Cart </Link> </div> </div> </div> </> ); }; const ShowSimilarProduct = () => { return ( <> <div className="py-4 my-4"> <div className="d-flex"> {similarProducts.map((item) => { return ( <div key={item.id} className="card mx-4 text-center"> <img className="card-img-top p-3" src={item.image} alt="Card" height={300} width={300} /> <div className="card-body"> <h5 className="card-title"> {item.title.substring(0, 15)}... </h5> </div> <div className="card-body"> <Link to={`/product/${item.id}`} className="btn btn-dark m-1" > Buy Now </Link> <button className="btn btn-dark m-1" onClick={() => addProduct(item)} > Add to Cart </button> </div> </div> ); })} </div> </div> </> ); }; return ( <> <Navbar /> <div className="container"> <div className="row"> {ShowProduct()} <div className="row my-5 py-5"> <div className="d-none d-md-block"> <h2 className="">You may also Like</h2> <Marquee pauseOnHover={true} pauseOnClick={true} speed={50}> {ShowSimilarProduct()} </Marquee> </div> </div> </div> </div> <Footer /> </> ); }; export default Product;
关键修改说明
- 移除了冗余的
productData状态变量及错误的setProductData调用,解决初始化顺序错误。 - 将路由参数
id转为数字类型,确保和数据中的id类型匹配,正确筛选目标商品。 - 给
useEffect添加id依赖,路由参数变化时自动重新获取商品数据。 - 添加了
product为空时的加载提示,避免渲染空对象属性引发的错误。 - 优化了商品链接的写法,使用模板字符串
/product/${item.id}更简洁。
内容的提问来源于stack exchange,提问作者Alex Amiriyan
相关产品推荐
相关产品推荐

