开发者问题收集

无法在 React 中读取未定义的属性(读取‘map’)

2021-09-25
9168

我正在尝试使用 commerce.js 库创建一个电子商务网站。库 API 中已经有 8 种产品。我有一个 Products.js 组件,我将从 App.js 获得的产品对象数组传递给 Product.js 组件。为此,我使用映射函数将每个对象作为 props 传递给 Product.js 组件。但我收到了此错误。我尝试注释掉映射块,并且只有控制台记录了来自 App.jsproducts 变量和 Products.js 中的 prop products ,在那里我得到了所有 8 种产品,所以那里没有问题。但我不明白为什么在映射函数中会出现这个错误。

App.js

import React, { useState, useEffect } from "react";
import { commerce } from "./lib/commerce";
import { Products, Navbar } from "./components";

function App() {
  const [products, setProducts] = useState([]);

  const fetchProduct = async () => {
    const data = await commerce.products.list();
    setProducts(data);
  };
  useEffect(() => {
    fetchProduct();
  }, []);

  console.log("products", products);

  return (
    <div className="App">
      <Navbar />
      <Products products={products} />
    </div>
  );
}

export default App;

Products.js

import React from "react";
import { Grid } from "@material-ui/core";
import Product from "./Product/Product";
import useStyles from "./style";

const Products = ({ products }) => {
  const classes = useStyles();

  return (
    <main className={classes.content}>
      <div className={classes.toolbar} />
      <Grid container justifyContent="center" spacing={4}>
        {products.data.map((product) => (
          <Grid item key={product.id} xs={12} sm={6} md={4} lg={3}>
            <Product product={product} />
          </Grid>
        ))}
      </Grid>
    </main>
  );
};

export default Products;

Product.js

import React from "react";
import {
  Card,
  CardMedia,
  CardContent,
  CardActions,
  Typography,
  IconButton,
} from "@material-ui/core";
import { AddShoppingCart } from "@material-ui/icons";
import useStyles from "./styles";

const Product = ({ product }) => {
  const classes = useStyles();
  return (
    <Card className={classes.root}>
      <CardMedia
        className={classes.media}
        image={product.media.source}
        title={product.name}
      />
      <CardContent>
        <div className={classes.cardContent}>
          <Typography variant="h5" gutterBottom>
            {product.name}
          </Typography>
          <Typography variant="h5">
            {product.price.formatted_with_symbol}
          </Typography>
        </div>
        <Typography
          variant="body2"
          dangerouslySetInnerHTML={{ __html: product.description }}
        />
      </CardContent>
      <CardActions disableSpacing className={classes.cardActions}>
        <IconButton aria-label="Add to Cart">
          <AddShoppingCart />
        </IconButton>
      </CardActions>
    </Card>
  );
};

export default Product;
2个回答

在您的 App.js 中,按如下方式更改您的 fetchProduct 函数:

const fetchProduct = async = {
    const products = await commerce.products.list();
    setProducts(products.data);
}

然后在您的 Products.js 中映射产品而不是 products.data,

{products.map((product) => (
          <Grid item key={product.id} xs={12} sm={6} md={4} lg={3}>
            <Product product={product} />
          </Grid>
      ))}

说明:
产品的初始状态是一个空数组,它被传递给产品组件,您尝试了 products.data.map() ,但产品是一个数组(最初),并且数组上没有数据属性,因此它引发了错误。
有几种方法可以解决这个问题,但是 如果 您只使用来自响应的产品数据,那么您可以采用上述方法,即映射 products 而不是 products.data 并使用产品数组而不是产品进行 setProducts() 对象。

userharis
2021-09-25

您能将错误屏幕附加到附件吗?

我认为,您尝试在加载之前读取数据,您可以通过添加类似这样的内容来防止这种情况 (products.data || []).map 例如..或者在 useState({data:[]}) 上更改 App.js 中的默认状态

Waker
2021-09-25