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

React中props传递异常:product属性为何无法正确传入?

问题:ProductCard组件中product属性为undefined,页面无内容渲染

我正在用ProductCard组件将product对象传递至ProductPage页面,product对象应包含id、categoryId、name、price和img键值对。我通过对产品数组过滤、映射,获取特定分类的产品后将整个对象传入组件,但目前打印product得到undefined,页面也无内容渲染。

ProductsPage代码

const ProductsPage = () => {
  const [toggle, setToggle] = useState(false);
  const [categoryId, setCategoryId] = useState(0);

  const show = (id) => {
    if (toggle === id) return setToggle(null);

    setToggle(id);
    setCategoryId(id);
  };

  return (
    <div className="products-page">
      <div className="container">
        <section className="product-banner">
          <h3>All Products</h3>
        </section>
        <div className="product-categories">
          {categories.map((cat) => (
            <div key={cat.id}>
              <section
                onClick={() => show(cat.id)}
                className="cat-toggle"
              >
                <h4>{cat.name}</h4>
              </section>
              {toggle === cat.id && (
                <section className="products">
                  {products.filter((item) => item.categoryId === categoryId).map(filteredProduct => (
                    <ProductCard key={filteredProduct.id} product={filteredProduct} />
                  ))}
                </section>
              )}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

ProductCard组件代码

import React from "react";
import { Link } from "react-router-dom";

import "./ProductCard.scss";

const ProductCard = ({ product }) => {
  return (
    <Link className="link" to={`/products/${product.id}`}>
      <div className="product-card">
        <div className="product-img">
          <img src={product.img} alt={product.name} />
        </div>
        <div className="product-info">
          <p>${product.price}</p>
          <h5>{product.name}</h5>
        </div>
      </div>
    </Link>
  );
};

export default ProductCard;

我尝试过用react-router-dom的Link组件通过state={{ product: {product} }}传递属性,但结果一致。


问题排查与解决方法

1. 状态更新异步导致过滤不匹配

show函数中同时更新toggle和categoryId,但React状态更新是异步的,点击分类后,第一次渲染时categoryId可能还未更新,导致过滤条件失效;另外初始categoryId设为0,如果产品数组中没有categoryId=0的产品,初始过滤结果为空。

解决:直接使用当前循环的cat.id做过滤,无需依赖categoryId状态:

{toggle === cat.id && (
  <section className="products">
    {products.filter((item) => item.categoryId === cat.id).map(filteredProduct => (
      <ProductCard key={filteredProduct.id} product={filteredProduct} />
    ))}
  </section>
)}

2. 未处理product为空的边界情况

如果过滤结果为空或product未正确传递,直接访问product.id会报错,需添加空值检查:

const ProductCard = ({ product }) => {
  if (!product) return null;
  return (
    <Link className="link" to={`/products/${product.id}`}>
      <div className="product-card">
        <div className="product-img">
          <img src={product.img} alt={product.name} />
        </div>
        <div className="product-info">
          <p>${product.price}</p>
          <h5>{product.name}</h5>
        </div>
      </div>
    </Link>
  );
};

3. 检查数据源正确性

确认products数组中每个元素都包含categoryId、id等必填字段,且categories的id与products的categoryId完全匹配,可以在过滤前打印products和cat.id验证匹配情况。

4. Link传参的正确写法

如果要跳转到ProductPage时传递product数据,正确写法是:

<Link className="link" to={`/products/${product.id}`} state={{ product }}>

在ProductPage中通过useLocation接收:

import { useLocation } from 'react-router-dom';

const ProductPage = () => {
  const location = useLocation();
  const product = location.state?.product;
  // 后续渲染逻辑
};

避免写成state={{ product: {product} }},这会导致product被嵌套在另一个对象中,无法直接获取。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 09:34:59