MERN栈新手求助:数据库取数渲染卡片报错问题
MERN栈商品卡片渲染问题修正
问题原因梳理
你遇到的"Unexpected response format from server"错误主要来自以下几个问题:
- 前端判断条件错误:后端返回的商品数据在
res.data.data.product,但你判断的是res.data.product,导致条件不满足触发错误提示 - CardMedia组件使用错误:不能直接在CardMedia标签内嵌套map循环,且当前结构只会渲染一张卡片,应该把整个Card放在循环中遍历所有商品
- 状态初始化不合理:error初始化为数组类型,应该是字符串;product初始值可以设为空数组,避免初始渲染的冗余占位
- 模型字段设置错误:
prize字段设置了unique,价格重复是正常场景,应该移除该约束
修正后的代码
React组件代码
import React, { useEffect, useState } from 'react' import Card from '@mui/material/Card'; import CardContent from '@mui/material/CardContent'; import CardMedia from '@mui/material/CardMedia'; import Typography from '@mui/material/Typography'; import { Button, CardActionArea, CardActions } from '@mui/material'; import axios from 'axios'; export default function ProductItems() { // 初始化空数组,避免冗余占位 const [products, setProducts] = useState([]); // error初始化为空字符串 const [error, setError] = useState(''); useEffect(() => { axios.get('http://localhost:5000/getProduct') .then(res => { // 修正判断条件,匹配后端返回结构 if(res.data.status === 'success' && res.data.data.product){ setProducts(res.data.data.product); }else{ setError('Unexpected response format from server'); } }) .catch(err => { if(err.response && err.response.status === 403){ setError('Access Denied'); }else{ setError('Error fetching from server'); } }); },[]); const cardStyle = { display: 'inline-block', width: '30vw', height: '45vw', margin: '10px' }; return ( <div style={{padding: '20px'}}> {/* 遍历products数组,每个商品渲染一张Card */} {products.map((product, index) => ( <Card key={index} sx={{ maxWidth: 345 }} style={cardStyle}> <CardActionArea> {/* 正确使用CardMedia的image属性 */} <CardMedia component="img" height="140" image={product.img} alt={product.title} /> <CardContent> <Typography gutterBottom variant="h4" component="div"> {product.title} </Typography> <Typography variant="h5" color="text.secondary"> ${product.prize} </Typography> </CardContent> </CardActionArea> <CardActions> <Button size="medium" variant="contained" sx={{bgcolor:"#c85959", "&:hover":{bgcolor:"#4f0b0b"}}} > Shop Now </Button> </CardActions> </Card> ))} {/* 错误提示放在外层,避免重复渲染 */} {error && <p style={{color:'red', marginTop: '20px'}}>{error}</p>} </div> ) }
Product模型代码
const mongoose = require("mongoose") const ProductSchema = new mongoose.Schema( { title: {type: String, required:true, unique:true}, // 移除unique约束,价格允许重复 prize:{type:Number, required:true}, description: {type:String, required:true}, img: {type:String, required:true}, categories: {type:Array, required:true}, size: {type:Array, required:true}, colour: {type:String, required:true}, }, {timestamps: true} ); module.exports = mongoose.model("Product", ProductSchema);
getProduct路由代码(优化后)
const router = require("express").Router(); const Product = require("../database/models/Product") router.get("/", async(req, res) => { try{ // 将await放入try块内,避免未捕获的异步错误 const product = await Product.find({}); res.status(200).json({ status: 'success', data:{ product } }); }catch(err){ res.status(500).json({ status: 'Failed', message: err.message // 添加错误信息,便于后端调试 }); } }) module.exports = router;
内容的提问来源于stack exchange,提问作者WADD Samindika
相关产品推荐
相关产品推荐

