React js TypeError:无法读取未定义的属性“ map”

时间:2020-09-20 18:06:35

标签: javascript reactjs

使用地图功能进行渲染时出现错误。它显示:

typeError无法读取未定义的属性'map'

这是我所有的组件文件:

菜单component.js

    import React, {Component} from 'react';
    import { Card, CardImg, CardImgOverlay,
        CardTitle } from 'reactstrap';

    import DishDetail from './DishdetailComponent';

    class Menu extends Component {

        constructor(props) {
            super(props);
        }

        renderDish(dish) {
            if(dish != null){
                return(
                    <DishDetail dish={dish}/>
                );
            }
            else{
                return(
                    <div></div>
                )
            }
        }

        render() {
            const menu = this.props.dishes.map((dish) => {
                return (
                <div className="col-12 col-md-5 m-1">
                    <Card key={dish.id} onClick={() => this.props.onClick(dish.id)}>
                    
                    <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>
            );
        }
    }

    export default Menu;

DishdetailComponent.js

    import React , { Component } from 'react';
    import { Card, CardBody, CardImg, CardText, CardTitle } from 'reactstrap';


    class DishDetail  extends Component{

        constructor(props) {
            super(props);

            this.state = {
                selectedDish: null
            }
        }

        renderDish(dish){
            if(dish != null){
                return(
                    <Card>
                        <CardImg top  width="100%" src={dish.image} alt={dish.name} />
                        <CardBody>
                            <CardTitle>{dish.name}</CardTitle>
                            <CardText>{dish.description}</CardText>
                        </CardBody>
                    </Card>
                );
            }
            else{
                return(
                    <div></div>
                );
            }
        }

        renderComments(comments){
            if(comments != null){
                return(
                    <div className="container">
                        <h4>Comments</h4>
                        {comments.map((comment) => {
                            let date = new Intl.DateTimeFormat('en-US', {
                                year:'numeric',
                                month: 'short',
                                day: '2-digit'
                            }).format(new Date(Date.parse(comment.date)))
                            return(
                                <ul className="list-unstyled" key={comment.id}>
                                    <li className="comment">{comment.comment}</li>
                                    <br/>
                                    <li className="author">-- {comment.author}, {date}</li>
                                </ul>
                            );
                            })}
                    </div>
                )

            }
            else{
                return(
                    <div></div>
                )
            }
        }

        render(){

            const selectedDish = this.props.dish;

            return(
                <div className="container">
                    <div className="row">
                        <div className="col-12 col-md-5 m-1">
                            {this.renderDish(selectedDish)}
                        </div>
                        <div className="col-12 col-md-5 m-1">
                            {this.renderComments(selectedDish.comments)}
                        </div>
                    </div>
                </div>
            )
        }

    }

    export default DishDetail;

MainComponent.js

    import React,{ Component } from 'react';
    import { Navbar, NavbarBrand } from 'reactstrap';
    import Menu from './MenuComponents';
    import DishDetail from './DishdetailComponent'
    import { DISHES } from '../shared/shareDishes.js';

    class Main extends Component {

    constructor(props) {
        super(props);

        this.state = {
        dishes: DISHES,
        selectedDish: null 
        }; 
    }

    onDishSelect(dishId) {
        this.setState({ selectedDish: dishId });
    }

    render() {
        return (
        <div>
            <Navbar dark color="primary">
            <div className="container">
                <NavbarBrand href="/">Ristorante confusion</NavbarBrand>
            </div>
            </Navbar>
            <Menu dishes = {this.state.dishes} 
                onClick={(dishId) => this.onDishSelect(dishId)} />
            <DishDetail dish={this.state.dishes.filter((dish) => dish.id === this.state.selectedDish[0])}/>
        </div>
        );
    }
    
    }

    export default Main;

这是sharedDishes.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"
                }
            ]
            }
    ] 

我使用id从另一个文件中的数组对象获取数据,并使用map函数对其进行迭代。但是虽然渲染功能它显示了我检查过的TypeError,但是我找不到未定义的属性。该如何解决?

2 个答案:

答案 0 :(得分:1)

确保dishescommentstruthy且是Array

Array.isArray(this.props.dishes)  && this.props.dishes.map(...)


Array.isArray(comments) && comments.map(...)

祝你好运...

答案 1 :(得分:0)

在初始化Main.js组件中的状态时,尝试将null的selectedDish值从null更改为0。

  this.state = {
        dishes: DISHES,
        selectedDish: 0 
        }; 
    }

另外,将 key = {dish.id} 从Card上移至包装div

<div className="col-12 col-md-5 m-1" key={dish.id}>

CodeSandbox

在DishDetail.js组件中,下一部分是多余的(实际上,目前在Menu和DishDetail中都是构造函数)

 this.state = {
   selectedDish: null
  }; 

因为该组件正在从Main.js组件接收selectDish作为道具。

希望这可以帮助您。

我建议坚持使用与组件相同的文件命名约定。例如, DishDetail.js 用于 类DishDetail扩展... Menu.js 用于< / strong> 类菜单扩展... ,并在源目录中创建这些组件文件夹-这些组件文件的 src / components /

祝一切顺利!