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

React传递ID后商品详情无法渲染,报'undefined is not an object'错误

问题分析与解决方案

问题描述

React项目渲染商品详情页时抛出错误:undefined is not an object (evaluating 'product.title')。当把Fixture中的数字类型id改为字符串类型后,详情页可正常显示,但Django REST API(DRF)返回的id仅支持数字类型。

问题根源

核心原因是类型不匹配:

  • DRF返回的商品id是数字类型(例如1)
  • React Router的useParams()获取到的URL参数id是字符串类型(例如"1")
  • 在Detail.js中使用products.find((product) => product.id === id)时,===是严格全等匹配,数字与字符串类型不相等,导致无法找到匹配的商品,最终product变量为undefined,访问product.title就会触发报错。

修复方案

推荐优先使用方案1(保持严格匹配的严谨性):

方案1:将URL参数转为数字类型

在Detail.js中把字符串类型的id转换为数字后再进行匹配,同时增加空值判断避免渲染报错:

function Detail() {
  const { id } = useParams();
  // 转换URL参数为数字类型
  const productId = Number(id);
  const { product } = useProduct(
    ({ state: { products } }) => ({
      product: products.find((product) => product.id === productId),
    }),
    true
  );   

  // 处理商品不存在的情况
  if (!product) {
    return <div>商品不存在或已下架</div>;
  }

  return (
      <div>
          <h1>{product.title}</h1>
          <p>Price: ${product.price}</p>
          <p>{product.overview}</p>
      </div>
  )
}

方案2:使用非严格匹配(==)

如果不想做类型转换,可以将严格全等===改为非严格全等==,它会自动进行类型转换后匹配:

const { product } = useProduct(
  ({ state: { products } }) => ({
    product: products.find((product) => product.id == id),
  }),
  true
);   

⚠️ 注意:这种方式不够严谨,可能出现意料外的匹配(例如1 == "1"、0 == false),仅临时场景使用。

额外优化建议

在Product.js中同样增加product空值判断,避免数据加载过程或异常情况下的报错:

function Product({ id }) {
  const { product } = useProduct(
    ({ state: { products } }) => ({
      product: products.find((product) => product.id === id),
    }),
    true
  );

  if (!product) {
    return <div className='col-3'>加载中...</div>;
  }
 
  return (
    <div className='col-3'>
      {/* 原组件渲染内容 */}
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 10:03:08