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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 16:25:35