I've somehow broke my working React code, and I can't figure out why. I'm new to learning React and so far all my attempts to fix it have gone unfounded and it's possible I've made it worse.
I have 4 "menu" cards. When you click on a menu card, a new card pops up on the bottom left with some additional info on that menu item, as well as comments about the menu item on the bottom right.
I have a DishDetail component that renders that selectedDish information. The component mounts and renders, but my dishdetail renders null
My main component renders the Menu component and dishdetail component:
import React, { Component } from 'react';
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
};
}
//sets the state of the selected Dish
onDishSelect(dishId) {
this.setState({ selectedDish: dishId});
}
//Renders the page with all its subcomponents
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;
The menu component renders the 4 menu cards
import React from 'react';
import { Card, CardImg, CardImgOverlay, CardText, CardBody, CardTitle } from 'reactstrap';
function RenderMenuItem({ dish, onClick }) {
return(
<Card key={dish.id}
onClick={() => props.onClick(dish.id)}>
<CardImg width="100%" src={dish.image} alt={dish.name} />
<CardImgOverlay>
<CardTitle>{dish.name}</CardTitle>
</CardImgOverlay>
</Card>
);
}
const Menu = (props) => {
const menu = props.dishes.map((dish) => {
return (
<div key={dish.id} className="col-12 col-md-5 m-1">
<RenderMenuItem dish={dish} onClick={props.onClick} />
</div>
);
});
//then returns a container of the menu
return (
<div className="container">
<div className="row">
{menu}
</div>
</div>
);
}
export default Menu;
The dishdetail component is supposed to render the menu/dish item information
import React from 'react';
import { Card, CardImg, CardImgOverlay, CardText, CardBody, CardTitle } from
'reactstrap';
function RenderDish({dish}) {
if (dish != null)
return(
<div className="col-12 col-md-5 m-1">
<Card>
<CardImg top src={dish.image} alt={dish.name} />
<CardBody>
<CardTitle>{dish.name}</CardTitle>
<CardText>{dish.description}</CardText>
</CardBody>
</Card>
</div>
);
else
return(
<div>For Some Reason, dish is null</div>
);
}
function RenderComments({comments}){
if (comments != null){
const coms = comments.map((com) => {
return(
<ul key={com.id} className='list-unstyled'>
<li>
{com.comment}
</li>
<li>
-- {com.author}, { }
{
new Intl.DateTimeFormat('en-US', {
month: 'short', day: '2-digit', year: 'numeric'
}).format(new Date(com.date))
}
</li>
</ul>
);
});
return(
<div className="col-12 col-md-5 m-1">
<h4>Comments</h4>
{coms}
</div>
);}
else{
return(
<div>For Some reason, comments are null</div>
);
}
}
const DishDetail = (props) => {
return (
<div className="container">
<div className="row">
<RenderDish dish={props.dish} />
<RenderComments comments={props.comments} />
</div>
</div>
)
}
export default DishDetail;
Theres also a file that contains the information for all the individual menu items.
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"
}
]
}
];
I think the break is somewhere between the dishId and passing that information to the dishdetail component, but I don't quite understand why. I'm new to React so I'm having a hard time visualizing/troubleshooting this.
CodePudding user response:
Fixes are given below.
1. `props.onClick` to `onClick`.
function RenderMenuItem({ dish, onClick }) {
return (
<Card key={dish.id} onClick={() => onClick(dish.id)}>
<CardImg width="100%" src={dish.image} alt={dish.name} />
<CardImgOverlay>
<CardTitle>{dish.name}</CardTitle>
</CardImgOverlay>
</Card>
);
2. `props.comments` to `props.dish.comments`. To avoid first time invalid access of empty `dish` object for comments insert `null` check.
const DishDetail = (props) => {
return (
<div className="container">
<div className="row">
<RenderDish dish={props.dish} />
{props.dish != null && (
<RenderComments comments={props.dish.comments} />
)}
</div>
</div>
);
};
CodePudding user response:
you're destructuring the onClick prop on the RenderMenuItem component and trying to reference props.onClick
CodePudding user response:
You have 2 problems:
- To solve the issue with the non-rendering card, you need to remove "props." from the onClick. It is no longer needed when the props are defined in the function;
...
function RenderMenuItem({ dish, onClick }) {
return(
<Card key={dish.id}
onClick={() => onClick(dish.id)}>
<CardImg width="100%" src={dish.image} alt={dish.name} />
<CardImgOverlay>
<CardTitle>{dish.name}</CardTitle>
</CardImgOverlay>
</Card>
);
}
...
- To solve the issue of the missing comment section, you need to reference the props of the parent dish before the comments in the DishDetail function; "props.comments" should be "props.dish.comments" (Edit: This worked temporarily and no longer is working though I'm not sure why. If I make this change the comments show up until the page is refreshed and it says "props.dish is undefined".)
...
const DishDetail = (props) => {
return (
<div className="container">
<div className="row">
<RenderDish dish={props.dish} />
<RenderComments comments={props.dish.comments} />
</div>
</div>
)
}
...