Im new to react.js and have been facing this issue.Im working on this app dishes where the user clicks one dish and then it is rendered in form a card.The value of dish is passed as a props from menucomponent to DishDetail but in doing so the dish object is always receiving null value for which there is nothing on the screen . please help me with it.im attaching both MenuComponents.js and DishDetail.js
the MenuComponent.js is:
import React, { Component } from 'react';
// import { Media } from 'reactstrap';
import { Card, CardImg, CardImgOverlay, CardText, CardBody,CardTitle } from 'reactstrap';
import DishDetail from './DishdetailComponent';
class Menu extends Component {
constructor(props) {
super(props);
this.state = {
selectedDish: null
};
}
onDishSelect(dish) {
this.setState({ selectedDish: dish});
}
render() {
const menu = this.props.dishes.map((dish) => {
return(
<div key={dish.id} className="col-12 col-md-5 m-1">
{/* <Media tag="li">
<Media left middle>
<Media object src={dish.image} alt={dish.name} />
</Media>
<Media body className="ml-5">
<Media heading>{dish.name}</Media>
<p>{dish.description}</p>
</Media>
</Media> */}
<Card key={dish.id} onClick={() => this.onDishSelect(dish)}>
<CardImg width="100%" src={dish.image} alt={dish.name} />
<CardImgOverlay>
<CardTitle>{dish.name}</CardTitle>
</CardImgOverlay>
</Card>
</div>
);
});
return(
<div className="container">
<div className="row">
{/* <Media list>
{menu}
</Media> */}
{menu}
</div>
<DishDetail dish={this.state.selectedDish} />
</div>
);
}
}
export default Menu;
the DishDetail.js is:
import React, { Component } from 'react';
import { Card, CardImg, CardImgOverlay, CardText, CardBody,CardTitle } from 'reactstrap';
class DishDetail extends Component{
constructor(props){
super(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>
);
}
render() {
const dish = this.props.selectedDish;
console.log(dish);
return(
<div className="row">
<div className="col-12 col-md-5 m-1">
{this.renderDish(this.props.selectedDish)}
</div>
<div className="col-12 col-md-5 m-1">
</div>
</div>
);
}
}
export default DishDetail;
You're passing a property named dish to your component but using selectedDish.
<DishDetail dish={this.state.selectedDish} />
const dish = this.props.selectedDish;
The prop passed to the DishDetail component is called dish:
// MenuComponent.js
<DishDetail dish={this.state.selectedDish} />
However DishDetail is expecting a prop with the name selectedDish:
// DishDetail.js
const dish = this.props.selectedDish;
{this.renderDish(this.props.selectedDish)}
Updating DishDetail to use this.props.dish will resolve your issue:
const dish = this.props.dish;
{this.renderDish(this.props.dish)}
Related
I am trying to build an application using react but I got an error saying "cannot read property 'image' of undefined"
Please help me if you found any issue because I am new in this framework.
The error showing up
function RenderCard({ item }) {
5 | return (
6 | <Card>
> 7 | <CardImg src={item.image} alt={item.name} />
8 | <CardBody>
9 | <CardTitle>{item.name}</CardTitle>
10 | {item.designation ? <CardSubtitle>{item.designation}</CardSubtitle> : null}
Full Code
import React from "react";
import { Card, CardImg, CardText, CardBody, CardTitle, CardSubtitle } from "reactstrap";
function RenderCard({ item }) {
return (
<Card>
<CardImg src={item.image} alt={item.name} />
<CardBody>
<CardTitle>{item.name}</CardTitle>
{item.designation ? <CardSubtitle>{item.designation}</CardSubtitle> : null}
<CardText>{item.description}</CardText>
</CardBody>
</Card>
);
}
function Home(props) {
return (
<div className="container">
<div className="row align-items-start">
<div className="col-12 col-md m-1">
<RenderCard item={props.dish} />
</div>
<div className="col-12 col-md m-1">
<RenderCard item={props.promotion} />
</div>
<div className="col-12 col-md m-1">
<RenderCard item={props.leader} />
</div>
</div>
</div>
);
}
export default Home;
And I'm importing it from another file
From my understanding there must be issue in importing the file
import React, { Component } from "react";
import Home from "./HomeComponent";
import Contact from "./ContactComponent";
import Menu from "./MenuComponents";
import Dishdetail from "./DishdetailComponent";
import Header from "./HeaderComponent";
import Footer from "./FooterComponent";
import { Dishes } from "../shared/dishes";
import { Comments } from "../shared/comments";
import { Leaders } from "../shared/leaders";
import { Promotions } from "../shared/promotions";
import { Switch, Route, Redirect } from "react-router-dom";
class Main extends Component {
constructor(props, context) {
super(props, context);
this.state = {
dishes: Dishes,
comments: Comments,
promotions: Promotions,
leaders: Leaders,
};
}
render() {
const HomePage = () => {
return (
<Home
dish={this.state.dishes.filter((dish) => dish.featured)[0]}
promo={this.state.promotions.filter((promo) => promo.featured)[0]}
leader={this.state.leaders.filter((leader) => leader.featured)[0]}
/>
);
};
const DishWithId = ({ match }) => {
return (
<Dishdetail
dish={this.state.dishes.filter((dish) => dish.id === parseInt(match.params.dishId, 10))[0]}
comments={this.state.comments.filter((comment) => comment.dishId === parseInt(match.params.dishId, 10))[0]}
/>
);
};
return (
<div>
<Header />
<Switch>
<Route path="/home" component={HomePage} />
<Route exact path="/menu" component={() => <Menu dishes={this.state.dishes} />} />
<Route path="/menu/:dishId" component={DishWithId} />
<Route exact path="/contactus" component={Contact} />
<Redirect to="/home" />
</Switch>
<Footer />
</div>
);
}
}
export default Main;
Thanks
You pass a promo prop to Home component:
<Home promo={...} />
But in Home component, you use using props.promotion which is undefined when it should be props.promo:
// don't use props.promotion, use props.promo instead
<RenderCard item={props.promo} />
im having problems trying to use the onclick function as props it sais when i clicked TypeError: onClick is not a function
What can i do!
7 | <Card
8 | onClick={() => onClick(dish.id)}>
| ^ 9 |
it is my first time using this kind of components
import React from 'react';
import { Card, CardImg, CardImgOverlay,
CardTitle } from 'reactstrap';
function RenderMenuItem ({dish, onClick}) {
return (
<Card
onClick={() => 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 className="col-12 col-md-5 m-1" key={dish.id}>
<RenderMenuItem dish={dish} onClick={props.onClick} />
</div>
);
});
return (
<div className="container">
<div className="row">
{menu}
</div>
</div>
);
}
export default Menu;
Try to have default props to avoid run time errors.
const Menu = (props) => {
const menu = props.dishes.map((dish) => {
return (
<div className="col-12 col-md-5 m-1" key={dish.id}>
<RenderMenuItem dish={dish} onClick={props.onClick} />
</div>
);
});
return (
<div className="container">
<div className="row">{menu}</div>
</div>
);
};
Menu.defaultProps = {
dishes: [],
onClick: () => {},
};
You must now use Menu component by providing valid function. For example <Menu onClick={dishId => {/* Logic /*}}/>
Hello good evening devs my problem is the following react when trying to load my application gives me the following error
Error React
import React from 'react';
import { Card, CardImg, CardText, CardBody, CardTitle } from 'reactstrap';
class DishDetail extends React.Component {
constructor(props) {
super(props);
this.state = {
}
}
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(dish) {
if (dish.comments != null) {
const comments = this.props.dish.comments.map(review => (
<div key={review.id}>
<ul className="list-unstyled">
{comments}
<li className="list-item">{review.comment}</li>
<li className="list-item">{review.author}</li>
<li className="list-item">{review.date}</li>
</ul>
</div>
));
}
else {
return (
<div></div>
);
}
return (
<div className="row">
<div className="col-12 col-md-5 m-1">
{this.renderDish(this.props.selectedDish)}
</div>
<div className="col-12 col-md-5 m-1">
<h4>comments</h4>
</div>
</div>
)
}
}
export default DishDetail;
I have made several changes to the code I am using the ES6 syntax, I would appreciate your help as I am trying to render from one component to another
The problem is in react class component you need to use render function to return the jsx you want to render if the last return is something you want to render then do it like this:
import React from 'react';
import { Card, CardImg, CardText, CardBody, CardTitle } from 'reactstrap';
class DishDetail extends React.Component {
constructor(props) {
super(props);
this.state = {
}
}
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(dish) {
if (dish.comments != null) {
const comments = this.props.dish.comments.map(review => (
<div key={review.id}>
<ul className="list-unstyled">
{comments}
<li className="list-item">{review.comment}</li>
<li className="list-item">{review.author}</li>
<li className="list-item">{review.date}</li>
</ul>
</div>
));
}
else {
return (
<div></div>
);
}
}
render(){
return (
<div className="row">
<div className="col-12 col-md-5 m-1">
{this.renderDish(this.props.selectedDish)}
</div>
<div className="col-12 col-md-5 m-1">
<h4>comments</h4>
<div>{this.renderComments(this.props.selectedDish)}</div>
</div>
</div>
)}
}
export default DishDetail;
import React, { Component } from "react";
import Product from "./Product";
import Title from "./Title";
import { ProductConsumer } from "../context";
export default class Productlist extends Component {
render() {
return (
<React.Fragment>
<div className="py-5">
<div className="container">
<Title name="our" title="products" />
<div className="row">
<ProductConsumer>
{value => {
return value.products.map(product => {
return <Product key={product.id} product={product} />;
});
}}
</ProductConsumer>
</div>
</div>
</div>
</React.Fragment>
);
}
}
Okay, I am getting this error and I am not quite sure what it is since I am so new to working with React.JS. could someone assist me in figuring out what may be happening.
export default class Product extends Component {
render() {
const { id, title, img, price, inCart } = this.props.product;
return (
<ProductWrapper className="col-9 mx-auto col-md-6 col-lg-3 my-3">
<div className="card">
<div
className="img-container p-5"
onClick={console.log("you clicked me on the image container")}
>
<Link to="/details">
<img src={img} alt="product" className="card-img-top" />
</Link>
</div>
</div>
</ProductWrapper>
);
}
}
const ProductWrapper = styled.div
Above is the Product code as asked! Thank you!
I have a parent component 'Menu' and a child component 'DishDetails'. The child component returns a Card on Button Click. It works for the first time when i click on the button. The component is not updated while i again click on button. The Component should update after clicking on the Button.
Parent Component
import React,{Component} from 'react';
import DishDetails from './DishDetails'
import { Card,CardImg,CardImgOverlay,CardTitle,CardBody,CardText} from 'reactstrap'
class Menu extends Component{
//The class base component must have a constructor with super statment
constructor(props){
super(props);
this.state ={
dishSelection:null
}
}
//Method when the user click on the image
onDish(dish){
this.setState({dishSelection:dish})
}
renderDish(dish){
if(dish!=null){
return(
<DishDetails dish = {dish}></DishDetails>
)
}
else{
return(
<div></div>
)
}
}
//The component should implement the render method
render(){
//Declare a variable for the defining the list
const media = this.props.dishes.map((dish)=>{
return(
<div className='col-12 col-md-5 m-2'>
<Card onClick={()=>this.onDish(dish)} key={dish.id}>
<CardImg src={dish.image} alt={dish.name} />
<CardImgOverlay>
<CardTitle>{dish.name}</CardTitle>
</CardImgOverlay>
</Card>
</div>
)
})
return(
<div className='container'>
<div className='row'>
{media}
</div>
<div className='row'>
<div className = 'col-12'>
{this.renderDish(this.state.dishSelection)}
</div>
</div>
</div>
)
}
}
export default Menu;
Child Component
import React , {Component} from 'react'
import {Card,CardImg,CardImgOverlay,CardTitle} from 'reactstrap'
class DishDetails extends Component{
constructor(props){
super(props)
this.state = {
dish : this.props.dish
}
}
render(){
//const dish = this.props.dish;
console.log(this.state.dish.name)
return(
<div>
<div className = 'col-12 col-md-5'>
<Card key={this.state.dish.id}>
<CardImg src={this.state.dish.image} alt={this.state.dish.name} />
<CardImgOverlay>
<CardTitle>{this.state.dish.name}</CardTitle>
</CardImgOverlay>
</Card>
</div>
<div>
</div>
</div>
)
}
}
export default DishDetails;
Constructor fires for the first time only. Don't make copy of props in state if you don't need to change the value inside child component. Change this.state.dish to this.props.dish in child component.
class DishDetails extends Component{
render(){
return(
<div>
<div className = 'col-12 col-md-5'>
<Card key={this.props.dish.id}>
<CardImg src={this.props.dish.image} alt={this.state.dish.name} />
<CardImgOverlay>
<CardTitle>{this.props.dish.name}</CardTitle>
</CardImgOverlay>
</Card>
</div>
<div>
</div>
</div>
)
}
}
export default DishDetails;
Or if you still want to update the state on any change in parent component then you should have a look at this link :-
https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops