为啥我的 React 应用程序会出现这个错误?

Posted

技术标签:

【中文标题】为啥我的 React 应用程序会出现这个错误?【英文标题】:Why am i getting this error in my React application?为什么我的 React 应用程序会出现这个错误? 【发布时间】:2021-11-08 09:55:27 【问题描述】:

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

导致这种情况的代码部分是我的 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; 

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

Maincomponent.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 组件

dishes.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.

【问题讨论】:

cmets.map((cmets) => 您正在映射 cmets 并将 t 带到相同的键 "cmets" 将其更改为 cmets.map((comment) => 【参考方案1】:

您在Main 中的初始状态是:

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

然后您将dishes 状态过滤到一个数组中,并将第0 个元素传递给dish 属性上的DishDetail

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

在初始渲染周期期间,过滤返回一个空数组,因为没有 dish 项具有空的 id 属性,因此 dish 属性未定义。

稍后在DishDetailrenderComments 中,您尝试通过this.props.dish.comments

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

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

解决方案

无论您传递dish 属性,您都应该在调用renderComments 之前首先检查this.props.dishthis.props.dish.comments 是否存在。

<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>

【讨论】:

【参考方案2】:

因为selectedDish 的初始值为空。所以filter 将返回一个空数组。而dish 将是undefined

您应该在返回之前检查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) />

【讨论】:

以上是关于为啥我的 React 应用程序会出现这个错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Axios fetch 会出现 CORS 错误?

React - 我的 App.js 文件中出现意外的标识符错误。我不明白为啥

React Element Type 无效,为啥会出现此错误,如何解决?

为啥我的 Laravel 应用程序会出现 ParseError? [关闭]

为啥我的 SwiftUI JSONDecoder 会出现致命错误?

为啥 ionic run ios 会出现“未找到匹配的配置文件”错误?