MERN项目中MongoDB数据无法在React页面显示的问题排查
MERN应用中MongoDB数据无法在React页面展示的排查与修复
问题描述
开发带路由的MERN应用时,遇到MongoDB数据无法在React的ProductCatalog组件页面展示的问题。直接访问http://localhost:3001/getProducts能看到原始格式的数据,但组件页面无内容渲染。已使用useEffect获取数据并设置状态,也用了map方法渲染,但无效。
组件代码
import Axios from 'axios'; import React, { useState, useEffect } from 'react' import { useNavigate } from 'react-router'; //Static images for page design import update from './images/update.png'; import del from './images/del.png'; import axios from 'axios'; export default function ProductCatalog() { const [products, setProducts] = useState([{}]) let index= 0; useEffect(() => { Axios.get('http://localhost:3001/getProducts').then((response) => { setProducts(response.data) }) }, []) let navigate = useNavigate(); function addProduct() { navigate('/adding') } function deleteProduct(id){ Axios.delete(`delete/${id}`) navigate('/delete') } function updateProduct(Product){ let Name = prompt("Please enter updated product name, or press OK:",Product.Name); let Description = prompt("Please enter udated description:",Product.Description); let Price = prompt("Please enter updated price:",Product.Price); let Stock = prompt("Please enter updated stock quantity:",Product.stock); let selectedImage = prompt("Please enter updated image address:",Product.selectedImage); axios.put('/update/'+Product._id, { Name, Description, Price, Stock, selectedImage }) navigate('/updated') } return( <React.Fragment> <button className="button" data-testid="addnewpage" onClick={addProduct}>Add New Product</button> <br></br> <div className="row"> {products.map((Product)=>{ let i = index; index++; return ( <div data-testid="renderProductList" className="before-footer-section product-section untree_co-section"> <div className="container"> <div className="col-12 col-lg-3 col-md-4 mb-5"> <a className="product-item" href="#"> <img src={Product.selectedImage} className="img-fluid product-thumbnail"/> <h3 className="product-title">{Product.Name}</h3> <strong className="product-price">{Product.Price}</strong> <p>{Product.Description}</p> <span className="icon-cross" onClick={() => updateProduct(Product)}> <img src={update} className="img-fluid"/> </span> <span className="icon-del" onClick={() => deleteProduct(Product._id)}> <img src={del} className="img-fluid"/> </span> </a> </div> </div> </div> ); })} </div> </React.Fragment> ) }
示例数据
[ { "_id": "63529c01e89851e73debb467", "Name": "Grey Swing Chair", "url": "grey-swing-chair", "Category": "Chairs", "Price": 501, "stock": 10, "Description": "Something designed to support a person in a sitting position, as a chair, bench, or pew; a place on or in which one sits", "selectedImage": "/images/product1.png", "__v": 0 } ]
问题排查与修复方案
初始状态设置不合理:将
products初始值设为[{}],会导致组件首次渲染时遍历空对象,即便后续数据加载成功,也可能因初始渲染的空结构干扰布局。建议改为[](空数组),这样首次渲染时map不会执行,避免无效内容。未处理请求错误:useEffect中的Axios请求没有错误捕获逻辑,若请求失败(跨域、后端接口异常等),
products状态不会更新,页面自然无内容。需补充错误处理:useEffect(() => { Axios.get('http://localhost:3001/getProducts') .then((response) => { setProducts(response.data) }) .catch(err => { console.error('获取数据失败:', err); }) }, [])接口路径不完整:
deleteProduct和updateProduct中的请求路径缺少后端基础域名,会默认发送到React应用所在域名(如localhost:3000),导致404。需修改为完整路径:// 删除接口 Axios.delete(`http://localhost:3001/delete/${id}`) // 更新接口 axios.put(`http://localhost:3001/update/${Product._id}`)字段大小写不匹配:更新接口中传递的
Stock是大写,但后端数据里的库存字段是stock(小写),会导致后端无法正确接收值,需改为一致的stock。渲染结构冗余:map循环内重复渲染
before-footer-section和container,会导致每个产品都生成独立的容器结构,破坏布局。应将这两个容器移到循环外,仅在循环内渲染产品列:return( <React.Fragment> <button className="button" data-testid="addnewpage" onClick={addProduct}>Add New Product</button> <br></br> <div className="before-footer-section product-section untree_co-section"> <div className="container"> <div className="row"> {products.map((Product, index)=>{ return ( <div data-testid="renderProductList" className="col-12 col-lg-3 col-md-4 mb-5"> <a className="product-item" href="#"> <img src={Product.selectedImage} className="img-fluid product-thumbnail"/> <h3 className="product-title">{Product.Name}</h3> <strong className="product-price">{Product.Price}</strong> <p>{Product.Description}</p> <span className="icon-cross" onClick={() => updateProduct(Product)}> <img src={update} className="img-fluid"/> </span> <span className="icon-del" onClick={() => deleteProduct(Product._id)}> <img src={del} className="img-fluid"/> </span> </a> </div> ); })} </div> </div> </div> </React.Fragment> )
内容的提问来源于stack exchange,提问作者shiz
相关产品推荐
相关产品推荐

