1

我在编译我的反应应用程序时收到此错误:TypeError: Cannot read properties of undefined (reading 'comments')。

导致这种情况的代码部分是我的 Dishdetailcomponent.js 的第 85 行

Dishdetailcomponent.js

import { Card, CardImg, CardImgOverlay, CardText, CardBody,
    CardTitle } from 'reactstrap';

class DishDetail extends Component {

    constructor(props) {
        super(props);

    }

    componentDidMount(){
        console.log('Dishdetail componentDidMount is invoked');
    }

    componentDidUpdate(){
        console.log('Dishdetail componentDidMount is invoked');
    }

    componentWillReceiveProps(props) {
        this.setState({ props: props })
      }

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

    renderComments(comments){
        console.log(comments);
        var commentsL = {}
        if (comments != null){
            commentsL = comments.map((comments) => {
            return (
            <ul class="list">
            <uli class="list-item" id = {comments.id}>
                    <div className="row">
                        {comments.comment}
                    </div>
                    <div className="row">
                        <p>--</p>{comments.author}&nbsp;{new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'short', day: '2-digit'}).format(new Date(Date.parse(comments.date)))}
                    </div>
            </uli>
            </ul>

        );
        }); }

        if (comments != null)
            return(
              <div>
                  <h4>Comments</h4>
                  {commentsL}
              </div>  
            );
        else
            return(
                <div></div>
            );
    }

    render() {
        console.log(this.props);
        console.log('Dishdetail component render is invoked');
        if (this.props != 'undefined')
            return (
            <div className="container">
                <div className="row">
                  <div  className="col-12 col-md-5 m-1">
                    {this.renderDish(this.props.dish)}
                  </div>
                  <div  className="col-12 col-md-5 m-1">
                    {this.renderComments(this.props.dish.comments)}
                  </div>
                </div>
            </div>
            );
    }
}

export default DishDetail; 

上面的组件是应该在页面末尾显示所选菜肴的演示组件。

主要组件.js

import { Navbar, NavbarBrand } from 'reactstrap';
import Menu from './MenuComponent';
import DishDetail from './DishdetailComponent';
import { DISHES } from '../shared/dishes';

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 Con Fusion</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;

上面的组件是容器组件,将 props 传递给 Dishdetail 组件

菜.js

    [
        {
        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"
            }
        ]
        }
    ];```

The file above contains the data of the dishes.

4

2 回答 2

1

你的初始状态Main是:

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

然后将状态过滤dishes到一个数组中,并将第 0 个元素传递给DishDetail道具dish

<DishDetail
  dish={this.state.dishes.filter((dish) => 
    dish.id === this.state.selectedDish)[0]
  }
/>

在初始渲染周期中,过滤返回一个空数组,因为没有任何dish项目具有 nullid属性,因此dishprop 是未定义的。

稍后在renderComments你们DishDetail尝试通过this.props.dish.comments

<div  className="col-12 col-md-5 m-1">
  {this.renderComments(this.props.dish.comments)}
</div>

由于this.props.dish未定义,您无法进一步访问该对象。

解决方案

但是,您传递一个dish道具,您应该首先检查它this.props.dishthis.props.dish.comments在调用之前存在renderComments

<div  className="col-12 col-md-5 m-1">
  {this.props.dish?.comments && this.renderComments(this.props.dish.comments)}
</div>

或者

<div  className="col-12 col-md-5 m-1">
  {this.props.dish 
    && this.props.dish.comments
    && this.renderComments(this.props.dish.comments)}
</div>
于 2021-09-13T03:58:05.997 回答
0

因为 的初始值为selectedDish空。所以filter会返回一个空数组。并且dishundefined

您应该检查this.props.dish返回前的值this.props

if (this.props.dish != 'undefined')
    return (

render() {
    console.log(this.props);
    console.log('Dishdetail component render is invoked');
    if (this.props.dish != 'undefined')
        return (
        <div className="container">
...

您应该使用find而不是filter在数组中查找元素。

<DishDetail dish={this.state.dishes.find((dish) => dish.id === this.state.selectedDish)} />
于 2021-09-13T03:57:53.430 回答