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

React项目中Product组件axios请求id未传入及map报错问题

问题:React中Product组件ID传递失败导致请求错误及渲染异常

有后端开发经验,转向前端后遇到首个问题:点击Home组件的View按钮跳转到Product组件时,无法将Product的Id传入axios请求,后端返回400错误,组件无法正常渲染,出现两类报错。

错误信息

请求错误

to load resource: the server responded with a status of 400 ()
 http://localhost:8080/product/undefined

渲染错误

items.map is not a function
TypeError: items.map is not a function
    at Product (http://localhost:3000/static/js/bundle.js:1085:67)
    at renderWithHooks (http://localhost:3000/static/js/bundle.js:26207:22)
    at updateFunctionComponent (http://localhost:3000/static/js/bundle.js:29089:24)
    at beginWork (http://localhost:3000/static/js/bundle.js:30801:20)
    at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:15799:18)
    at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:15843:20)
    at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:15900:35)
    at beginWork$1 (http://localhost:3000/static/js/bundle.js:35774:11)
    at performUnitOfWork (http://localhost:3000/static/js/bundle.js:35021:16)
    at workLoopSync (http://localhost:3000/static/js/bundle.js:34944:9)

相关组件代码

Product组件

import React, { useState, useEffect } from 'react';
import { useParams } from "react-router-dom";
import axios from 'axios';

const Product = () =>{
  const [items,setItems] = useState([]);
  const {id} = useParams();

useEffect(() => {
  fetchItems();
}, []); 

const fetchItems = () => {
    axios
        .get(
          `http://localhost:8080/product/${id}`
        )
        .then((res) => {
            setItems(res.data);
            console.log(res.product);
        })
        .catch((err) => {
          console.log(err)
        });
};
  return (
    <div>
      {items.map((item) =>(
          <div className='product-container' key={item.id}>
            <div>
              <img className='prod-image' src={item.imageURL} alt='' />
            </div>
            <div>
              <h2>{item.name}</h2>
              <p>{item.description}</p>
              <p>
                <strong>Price:</strong> {item.price}
              </p>
            </div>
          </div>
      ))}
    </div>
  );
};
export default Product;

Home组件(产品列表)

import React,{useState,useEffect} from 'react';
import axios from 'axios';
import { Link } from 'react-router-dom';

const Home = () => {
  const [products, setProducts] = useState([]);

useEffect(() => {
  fetchProducts();
}, []);

const fetchProducts = () => {
  axios
    .get('http://localhost:8080/product/')
    .then((res) => {
      console.log(res);
      setProducts(res.data);
    })
    .catch((err) => {
      console.log(err);
    });
};

  return (
    <div>
      <h1>Наша продукция</h1>
      <div className='item-container'>
        {products.map((product) => (
          <div className='card' key={product.id}>
            <img src={product.imageURL} alt='' />
            <h3>{product.name}</h3>
            <p>{product.description}</p>
            <a>{product.price} &#8381;</a>
              <Link to={`/product/${product.id}`}>View</Link>
          </div>
        ))}
      </div>
    </div>
  );
};

export default Home;

解决方案

1. 修复ID传递逻辑

Product组件中,useEffect依赖数组为空,导致组件挂载时可能还未获取到路由参数id,或路由参数更新时无法重新触发请求。需将id加入依赖数组:

useEffect(() => {
  fetchItems();
}, [id]); // 添加id作为依赖,确保id变化时重新请求

2. 调整单条数据的渲染逻辑

请求/product/${id}返回的是单个产品对象,而非数组,但原代码用了仅适用于数组的map方法,导致报错。需修改:

  • 将items初始状态改为null(表示未加载)
  • 渲染前先判断数据是否存在,直接渲染单个产品而非用map

修改后的Product组件核心代码:

const Product = () =>{
  const [item, setItem] = useState(null); // 初始状态设为null
  const {id} = useParams();

useEffect(() => {
  if (id) { // 确保id存在时才发起请求
    fetchItems();
  }
}, [id]); 

const fetchItems = () => {
    axios
        .get(`http://localhost:8080/product/${id}`)
        .then((res) => {
            setItem(res.data); // 直接存储单个产品对象
            console.log(res.data);
        })
        .catch((err) => {
          console.log(err)
        });
};

  return (
    <div>
      {item ? ( // 数据加载完成后渲染产品
          <div className='product-container' key={item.id}>
            <div>
              <img className='prod-image' src={item.imageURL} alt='' />
            </div>
            <div>
              <h2>{item.name}</h2>
              <p>{item.description}</p>
              <p>
                <strong>Price:</strong> {item.price}
              </p>
            </div>
          </div>
      ) : <div>加载中...</div>} // 未加载时显示占位内容
    </div>
  );
};

额外检查项

  • 确认后端/product/:id接口确实返回单个产品的JSON对象,而非数组
  • 检查Home组件中product.id是否为有效值,避免传递undefined到路由

内容的提问来源于stack exchange,提问作者Papahh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 07:52:53