如何解决React项目中TypeError: Cannot read property 'map' of undefined报错
提问内容还原
我目前遇到困难需要帮助!我是React纯新手,正在完成所学课程的实践作业,但反复遇到同类型问题,一直无法解决。
我不需要您帮我完成作业,若能得到代码问题定位的提示或指导/反馈,告知我哪里操作有误,我将不胜感激。我在谷歌、论坛都找不到解决方案,React技能还很薄弱,没有资深React开发者的帮助很难定位问题,提前非常感谢大家!:)
我一直遇到报错:TypeError: Cannot read property 'map' of undefined
完整源代码地址: 已移除外部链接
应用最终需求如下,供参考:
任务1:
- 在React应用中新增DishdetailComponent组件。
- 将DishDetail引入MenuComponent视图中,用于展示选中的菜品。
- 将选中的菜品作为props传递给DishDetail组件。
- 给卡片设置适配的Bootstrap类,使其在xs、sm屏幕尺寸下占满整行,md及以上屏幕占5列宽度。
- 给包含评论列表的div设置适配的Bootstrap类,使其在xs、sm屏幕尺寸下占满整行,md及以上屏幕占5列宽度。
任务2:
- 使用Card组件展示菜品详情。
任务3:
- 在dishdetail视图中加入对应菜品的评论列表。
相关代码
menuComponent.js
//package imports import React, { Component } from 'react'; //import bootrap components from reactstrap library //NOTE: The media query returns a CSS style import { Card, CardImgOverlay, CardImg, CardBody, CardText, CardTitle } from 'reactstrap'; import DishDetail from './DishdetailComponent'; //creates Menu component class Menu extends Component { //define a constructor for it constructor(props) { super(props); //when document is loaded no card has been selected by default this.state = { selectedDish: null }; } //when dish is clicked, it will render details of dish onDishSelect(dish) { this.setState({selectedDish: dish}); } //if dish is clicked it will show card details, else nothing 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> ) } } //return a value or function that will be called render() { //will iterate (map) over the dishes list and return each key (item) uniquely const menu = this.props.dishes.map((dish) => { // This will create the layout of the menu items by displaying the image, name and -description- of each menu item return ( <div key={dish.id} className="col-12 col-md-5 m-1"> {/* When clicked on, it will run event function*/} <Card onClick={() => this.onDishSelect(dish.id, dish.comments)}> <CardImg width="100%" src={dish.image} alt={dish.name} /> <CardImgOverlay body className="ml-5"> <CardTitle>{dish.name}</CardTitle> </CardImgOverlay> </Card> </div> ); }); return ( //This will return a menu list that will be defined <div className="container"> <div className="row"> {/* This will return the menu items */} {menu} </div> <div className="row"> {/* This will return the clicked card dish items when clicked */} <div className="col-12 col-md-5 m-1"> {this.renderDish(this.state.selectedDish)}, </div> <div className="col-12 col-md-5 m-1"> <DishDetail dishes={this.state.dishes} /> </div> </div> </div> ); } } //exports it for use in other files export default Menu;
DishdetailComponent.js
//package imports import React, { Component } from 'react'; //import bootrap components from reactstrap library //NOTE: The media query returns a CSS style //creates Dishdetail component class DishDetail extends Component { //define a constructor for it constructor(props) { super(props); //when document is loaded no card has been selected by default this.state = { selectedDish: null, comments: null }; } onDishSelect(comments) { this.setState({comments: comments}); } //if dish is clicked it will show card comments, else nothing renderComments(comments) { if (comments != null){ return ( <ul key={comments.id} className="list-unstyled"> <li className="comment">{comments.comment}</li> <li className="author"> {comments.author}</li> <li className="date"> {comments.date}</li> </ul> ) } else { return( <div></div> ) } } //return a value or function that will be called render() { //will iterate (map) over the dishes list and return each key (item) uniquely const details = this.props.comments.map((comments) => { return ( <div className="container"> <div className="row"> <div className="col-12 col-md-5 m-1"> <h4>Comments</h4> <div>{comments}</div> </div> </div> </div> ); }); return ( //This will return a menu list that will be defined <div className="container"> <div className="row"> {/* This will return the menu items */} {details} </div> <div className="row"> {/* This will return the clicked card dish items when clicked */} {this.renderComments(this.state.selectedDish)}, </div> </div> ); } } //exports it for use in other files export default DishDetail;
App.js
//package and component imports import logo from './logo.svg'; import React, {Component} from 'react'; import { NavbarBrand, Navbar } from 'reactstrap'; import Menu from './components/menuComponent'; import DishDetail from './components/DishdetailComponent'; import './App.css'; import {DISHES} from './shared/dishes'; //creates Menu component class App extends Component { //define a constructor for it constructor (props) { super(props); //when document is loaded no card has been selected by default this.state = { dishes: DISHES, selectedDish: null, comments: null }; } //when dish is clicked, it will render details of dish onDishSelect(dish) { this.setState({ selectedDish: dish}); } render () { return ( //To create html structures in React we always define it via the className strucutre <div> {/* This will create a layour based on our individual component files. For example, if we have a navbarComponent file, then we just import it from there and insert it here, without having to code the whole thing. */} <Navbar color="primary" dark expand="md"> <div className="container"> <NavbarBrand href="/"> Ristorante Con Fusion</NavbarBrand> </div> </Navbar> {/* The Menu component from the menuComponent.js file is rendered here and displayed when the index.js is loaded */} <Menu dishes={this.state.dishes} /> </div> ); } } //exports it for use in other files export default App;
内容的提问来源于stack exchange,提问作者christinec-dev
相关产品推荐
相关产品推荐

