[英]TypeError: Cannot read properties of undefined (reading 'map') (JavaScript array map)
[英]TypeError: Cannot read properties of undefined (reading 'map') - State returns undefined
我试图在 state 中检索一个数组,然后在 map 中检索 go,但返回未定义。 state 似乎还没有准备好,但不知道为什么。
我尝试了很多替代方案,但即使是我无法获得的长度,它也返回未定义。 只有 function getProductDetails 中的数据我可以得到长度,没有其他地方。 所以这就是为什么我认为这与 state 准备就绪有关,但不知道如何解决。
任何帮助,将不胜感激。
import React, { Component } from 'react';
import propTypes from 'prop-types';
import { Link } from 'react-router-dom';
import cartIcon from '../images/cartIcon.jpg';
import backIcon from '../images/backIcon.jpg';
import '../styles/ProductDetails.css';
export default class ProductDetails extends Component {
constructor() {
super();
this.state = {
product: {},
};
}
componentDidMount() {
this.getDetails();
}
async getProductDetails(item) {
const url = `https://api.mercadolibre.com/items/${item}`;
const response = await fetch(url);
const data = await response.json();
return data;
}
async getDetails() {
const { match: { params: { id } } } = this.props;
const product = await this.getProductDetails(id);
this.setState({
product,
});
}
render() {
const { product } = this.state;
return (
<section className="details">
<div className="details__header">
<div className="details__back">
<Link
to="/"
className="back__btn"
data-testid="shopping-back-button"
>
<img
id="back-button"
name="back-button"
alt="Voltar"
src={ backIcon }
className="back__img"
/>
</Link>
</div>
<div className="details__cart">
<Link
to="/carrinho-de-compras"
className="cart__btn"
data-testid="shopping-cart-button"
>
<img
id="cart-button"
name="cart-button"
alt="Carrinho de Compras"
src={ cartIcon }
className="cart__img"
/>
</Link>
</div>
</div>
<div className="details__product">
<div className="details__left">
<p data-testid="product-detail-name">{ product.title }</p>
<img src={ product.thumbnail } alt={ product.title } />
<p>{ product.id }</p>
<p>{ product.price }</p>
</div>
<div className="details__right">
<ul>
{(product.attributes)
.map(({ name, value_name: valueName }, index) => (
<li key={ index }>
{name}
:
{valueName}
</li>))}
</ul>
</div>
</div>
</section>
);
}
}
ProductDetails.propTypes = {
match: propTypes.shape({
params: propTypes.shape({
id: propTypes.string,
}),
}).isRequired,
};
那是因为您的this.state.product
只有在您调用this.getDetails()
以在componentDidMount
中获取和设置数据后才可用。
因此,当您的组件第一次渲染(又名挂载)时, this.state.product
将不可用。
为了解决这个问题,一种常见的方法是在render()
方法中检查this.state.product
像这样。
render() {
const { product } = this.state;
// if data is NOT available
if (!product) {
// either return null, or render a loading indicator, or whatever you want, while waiting for `this.state.product` to be available
return null
}
// if data is available
return (
<section className="details">
// render your component here
</section>
);
}
初始this.state.product
值是一个空的 object {}
,所以this.state.product.attributes
在初始渲染上是未定义的并且不可映射
this.state = {
product: {},
};
product.title
、 product.id
和product.price
在初始渲染中也是未定义的 OFC,但由于您没有更深入地访问,因此这些仅作为未定义值渲染到 DOM 并且不会引发错误。
您有几个选项可以防止可能的 null/undefined 访问:
在this.state.product.attributes
上使用 null-check/guard-clause
<ul> {product.attributes && product.attributes.map(({ name, value_name: valueName }, index) => ( <li key={index}> {name}: {valueName} </li> ))} </ul>
在this.state.product.attributes
上使用可选的链接运算符
<ul> {product.attributes?.map(({ name, value_name: valueName }, index) => ( <li key={index}> {name}: {valueName} </li> ))} </ul>
getProductDetails(item)
不会返回 promise,因此 getDetails() 中的getDetails()
await this.getProductDetails(id)
不会等待任何东西。 您必须在 getProductDetails 中返回 Promise,如下所示:
async getProductDetails(item) {
return new Promise(async (resolve, reject) => {
const url = `https://api.mercadolibre.com/items/${item}`;
const response = await fetch(url);
const data = await response.json();
resolve(data)
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.