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

如何解决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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 21:27:03