我一直遇到这个错误
从 dishes.js 导入TypeError:无法读取未定义的属性“ map”
DISHES
对象,并将其加载到 App.js 组件的状态对象盘中,然后将其作为道具传递给<通过 App.js
我不知道为什么,一切似乎都正确,这是一项在线课程的一部分,我已经看过其他参加过该课程的人所做的更正,他们似乎在做与我,对他们有用。
输出:
App.js
import React, {Component} from 'react';
import {Navbar, NavbarBrand} from 'reactstrap';
import './App.css';
import Menu from './components/MenuComponent';
import { DISHES } from "./shared/dishes";
class App extends Component {
constructor(props) {
super(props);
this.state = {
dishes: DISHES
};
}
render() {
return (
<div>
<Navbar dark color="primary">
<div className="container">
<NavbarBrand href="/">Ristorante Con Fusion</NavbarBrand>
</div>
</Navbar>
<Menu dishes={this.state.dishes}/>
</div>
);
}
}
export default App;
MenuComponent.js
import React, { Component } from 'react';
import { Card, CardImg, CardImgOverlay, CardText, CardBody, CardTitle } from 'reactstrap';
class Menu extends Component {
constructor(props) {
super(props);
this.state = {
selectedDish: null
};
}
onDishSelect(dish) {
this.setState({selectedDish: dish});
}
renderDish(dish) {
if (dish != null) {
return (
<Card>
<CardImg width="100%" src={dish.image} alt={dish.name}/>
<CardBody>
<CardTitle>{dish.name}</CardTitle>
<CardText>{dish.description}</CardText>
</CardBody>
</Card>
);
} else {
return (
<div></div>
);
}
}
render() {
const menu = this.props.dishes.map((dish) => {
return (
<div key={dish.id} className="col-12 col-md-5 m-1">
<Card onClick={() => this.onDishSelect(dish)}>
<CardImg width="100%" src={dish.image} alt={dish.name}/>
<CardImgOverlay>
<CardTitle>{dish.name}</CardTitle>
</CardImgOverlay>
</Card>
</div>
);
});
return (
<div className="container">
<div className="row">
{menu}
</div>
<div className="row">
{this.renderDish(this.state.selectedDish)}
</div>
</div>
);
}
}
export default Menu;
dishes.js
export const DISHES =
[
{
id: 0,
name:'Uthappizza',
image: 'assets/images/uthappizza.png',
category: 'mains',
label:'Hot',
price:'4.99',
description:'A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.',
comments: [
{
id: 0,
rating: 5,
comment: "Imagine all the eatables, living in conFusion!",
author: "John Lemon",
date: "2012-10-16T17:57:28.556094Z"
},
{
id: 1,
rating: 4,
comment: "Sends anyone to heaven, I wish I could get my mother-in-law to eat it!",
author: "Paul McVites",
date: "2014-09-05T17:57:28.556094Z"
},
{
id: 2,
rating: 3,
comment: "Eat it, just eat it!",
author: "Michael Jaikishan",
date: "2015-02-13T17:57:28.556094Z"
},
{
id: 3,
rating: 4,
comment: "Ultimate, Reaching for the stars!",
author: "Ringo Starry",
date: "2013-12-02T17:57:28.556094Z"
},
{
id: 4,
rating: 2,
comment: "It's your birthday, we're gonna party!",
author: "25 Cent",
date: "2011-12-02T17:57:28.556094Z"
}
] },
{
id: 1,
name:'Zucchipakoda',
image: 'assets/images/zucchipakoda.png',
category: 'appetizer',
label:'',
price:'1.99',
description:'Deep fried Zucchini coated with mildly spiced Chickpea flour batter accompanied with a sweet-tangy tamarind sauce',
comments: [
{
id: 0,
rating: 5,
comment: "Imagine all the eatables, living in conFusion!",
author: "John Lemon",
date: "2012-10-16T17:57:28.556094Z"
},
{
id: 1,
rating: 4,
comment: "Sends anyone to heaven, I wish I could get my mother-in-law to eat it!",
author: "Paul McVites",
date: "2014-09-05T17:57:28.556094Z"
},
{
id: 2,
rating: 3,
comment: "Eat it, just eat it!",
author: "Michael Jaikishan",
date: "2015-02-13T17:57:28.556094Z"
},
{
id: 3,
rating: 4,
comment: "Ultimate, Reaching for the stars!",
author: "Ringo Starry",
date: "2013-12-02T17:57:28.556094Z"
},
{
id: 4,
rating: 2,
comment: "It's your birthday, we're gonna party!",
author: "25 Cent",
date: "2011-12-02T17:57:28.556094Z"
}
]
},
{
id: 2,
name:'Vadonut',
image: 'assets/images/vadonut.png',
category: 'appetizer',
label:'New',
price:'1.99',
description:'A quintessential ConFusion experience, is it a vada or is it a donut?',
comments: [
{
id: 0,
rating: 5,
comment: "Imagine all the eatables, living in conFusion!",
author: "John Lemon",
date: "2012-10-16T17:57:28.556094Z"
},
{
id: 1,
rating: 4,
comment: "Sends anyone to heaven, I wish I could get my mother-in-law to eat it!",
author: "Paul McVites",
date: "2014-09-05T17:57:28.556094Z"
},
{
id: 2,
rating: 3,
comment: "Eat it, just eat it!",
author: "Michael Jaikishan",
date: "2015-02-13T17:57:28.556094Z"
},
{
id: 3,
rating: 4,
comment: "Ultimate, Reaching for the stars!",
author: "Ringo Starry",
date: "2013-12-02T17:57:28.556094Z"
},
{
id: 4,
rating: 2,
comment: "It's your birthday, we're gonna party!",
author: "25 Cent",
date: "2011-12-02T17:57:28.556094Z"
}
]
},
{
id: 3,
name:'ElaiCheese Cake',
image: 'assets/images/elaicheesecake.png',
category: 'dessert',
label:'',
price:'2.99',
description:'A delectable, semi-sweet New York Style Cheese Cake, with Graham cracker crust and spiced with Indian cardamoms',
comments: [
{
id: 0,
rating: 5,
comment: "Imagine all the eatables, living in conFusion!",
author: "John Lemon",
date: "2012-10-16T17:57:28.556094Z"
},
{
id: 1,
rating: 4,
comment: "Sends anyone to heaven, I wish I could get my mother-in-law to eat it!",
author: "Paul McVites",
date: "2014-09-05T17:57:28.556094Z"
},
{
id: 2,
rating: 3,
comment: "Eat it, just eat it!",
author: "Michael Jaikishan",
date: "2015-02-13T17:57:28.556094Z"
},
{
id: 3,
rating: 4,
comment: "Ultimate, Reaching for the stars!",
author: "Ringo Starry",
date: "2013-12-02T17:57:28.556094Z"
},
{
id: 4,
rating: 2,
comment: "It's your birthday, we're gonna party!",
author: "25 Cent",
date: "2011-12-02T17:57:28.556094Z"
}
]
}
];
答案 0 :(得分:2)
您拥有此组件<Menu dishes={this.state.dishes}/>
,该组件需要dishes
道具。
现在在<App>
中,您调用this.setState()
,但它是异步的,并且在<App>
(因此也是<Menu>
)的第一个呈现上,值{{1 }}仍为this.state.dishes
,因此undefined
中的this.props
也是<Menu>
当它确实更新时,将进行重新渲染,并且undefined
和<App>
将使用正确的值进行渲染。
因此,您可以添加对<Menu>
的检查,以使undefined
仅在.map()
有值时运行。
this.props
就是这样做的。从本质上讲,它的意思是this.props && this.props.dishes.map()
,因此,当if(this.props){ this.props.dishes.map() }
为this.props
时,将不执行第二个表达式。
完成undefined
之后,定义setState
,就可以得到结果。
答案 1 :(得分:1)
为避免任何道具未定义值,您可以使用库prop-types,在其中定义道具默认值,这样,如果道具值未传输到组件,则组件仍将具有默认值表现出预期。例如,在不从一开始就定义道具的情况下,这很有用。
为此,请安装库:
npm install --save prop-types
然后在您的MenuComponent
文件中,将导入内容添加到文件顶部:
import PropTypes from 'prop-types';
最后,在文件末尾,添加以下道具类型检查和默认值:
// Define the props types to check
Menu.propTypes = {
dishes: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.number,
name: PropTypes.string,
image: PropTypes.string,
category: PropTypes.string,
label: PropTypes.string,
price: PropTypes.string,
description: PropTypes.string,
comment: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.number,
rating: PropTypes.number,
comment: PropTypes.string,
author: PropTypes.string,
date: PropTypes.string,
})),
})),
};
// Define here the default value to attribute to your dishes props
Menu.defaultProps = {
dishes: [],
};
export default Menu;
希望这会有所帮助!
答案 2 :(得分:0)
我要上同一堂课,所以我没有问题地复制并粘贴了您的代码。确保index.js文件也是如此。如果这不是问题,则可能是您的导入已正确安装。由于MenuComponent存在问题,可能是反应未正确下载。
不确定是什么问题,但是我不认为这与代码有关。
import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();