React:prop eror - reactjs

I am trying to implement Presentational and Container Components using probs, but I get this error "Cannot read property 'image' of undefined" while trying to access an item passed using props.Below is the code I am using in order of Heirachy.The last class(DishDetail.js) has the problem
App.js
import React, { Component } from 'react';
import Main from './components/MainComponent.js';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<Main />
</div>
);
}
}
export default App;
MainComponent.js
import React, { Component } from 'react';
import { Navbar, NavbarBrand } from 'reactstrap';
import { DISHES } from '../shared/dishes';
import Menu from './MenuComponent';
import DishDetail from './DishDetail';
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;
MenuComponent.js
import React, { Component } from 'react';
import { Card, CardImg, CardImgOverlay, CardText, CardBody, CardTitle } from 'reactstrap';
class Menu extends Component {
constructor(props) {
super(props);
}
render() {
const menu = this.props.dishes.map((dish) => {
return (
<div key={dish.id} className="col-12 col-md-5 m-1">
<Card onClick={(dishId)=>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;
DishDetail.js
import React, { Component } from 'react';
import { Card, CardImg, CardImgOverlay, CardText, CardBody, CardTitle } from 'reactstrap';
class DishDetail extends Component {
constructor(props) {
super(props);
}
renderComments(comments){
const comment_layout= comments.map((comment)=>{
if(comment.comment!=null){
return(
<div>
<h4>Comment</h4>
{comment.comment}
{comment.author}, {new Intl.DateTimeFormat('en-US',{year:'numeric',month:'short',day:'2-digit'}).format(new Date(Date.parse(comment.date)))}
</div>
);
}else{
return(
<div></div>
);
}
});
return(comment_layout);
}
render() {
return (
<div className="row col-sm-12 col-12 m-1 container">
<div className="col-md-5 col-sm-12">
<Card>
<CardImg top src={this.props.dish.image} alt={this.props.dish.name}/>
<CardBody>
<CardTitle>{this.props.dish.name}</CardTitle>
<CardText>{this.props.dish.description}</CardText>
</CardBody>
</Card>
</div>
<div className="col-md-5 col-sm-12 m-1">
{this.renderComments(this.props.dish.comments)}
</div>
</div>
);
}
}
export default DishDetail;

Related

Error: Type '{ children: Element; }' has no properties in common with type 'IntrinsicAttributes & Pick<ClassAttributes<Layout>&Props, "ref" | "key">'

Error: Type '{ children: Element; }' has no properties in common with
type 'IntrinsicAttributes & Pick<ClassAttributes & Props,
"ref" | "key">'.
I'm new learner of reactjs with typescript and I follow the https://www.youtube.com/watch?v=8jHKBAPNtpM tutorial for learning, but things are not explained properly on this video.
Can Anyone help me for resolve this issue.
My HomePage.tsx file
import React, { Component } from "react";
import Layout from "../../components/common/layout";
import Content from "../../components/common/content";
import Home from "./../../components/home";
class HomePage extends Component {
render() {
return (
<div className="wrapper">
<Layout>
<Content title="Dashboard">
<Home />
</Content>
</Layout>
</div>
);
}
}
export default HomePage;
my Layout.tsx file
import React, { Component } from "react";
import { connect } from "react-redux";
import TopNav from "../topnav";
import Aside from "../aside";
import UserStateInterface from "../../../interfaces/UserStateInterface";
import UserService from "../../../services/UserService";
import { setUser } from "./../../../store/actions";
interface Props {
user: UserStateInterface;
setUser: typeof setUser;
}
class Layout extends Component<Props> {
async componentDidMount() {
const response = await UserService.getCurrentUserProfile();
this.props.setUser(response);
}
render() {
return (
<React.Fragment>
<TopNav />
<Aside user={this.props.user} />
{this.props.children}
</React.Fragment>
);
}
}
const mapStateToProps = (state) => {
return {
user: state.user,
};
};
export default connect(mapStateToProps, { setUser })(Layout);
my Content.tsx file
import React, { Component } from "react";
interface Props {
title: String;
}
class Content extends Component<Props> {
render() {
const { title } = this.props;
return (
<div className="content-wrapper">
<section className="content-header">
<div className="container-fluid">
<div className="row mb-2">
<div className="col-sm-6">
<h1>{title}</h1>
</div>
<div className="col-sm-6">
<ol className="breadcrumb float-sm-right">
<li className="breadcrumb-item">
<a href="/" onClick={(event) => event.preventDefault()}>
Home
</a>
</li>
<li className="breadcrumb-item active">Blank Page</li>
</ol>
</div>
</div>
</div>
</section>
<section className="content">{this.props.children}</section>
</div>
);
}
}
export default Content;
my Home.tsx file
import React, { Component } from "react";
import Card from "./../common/card";
import TopCards from "./topcards";
import TodoWrapper from "../todo/todowrapper";
class Home extends Component {
render() {
return (
<React.Fragment>
<TopCards />
<div className="row">
<div className="col-md-6">
<TodoWrapper />
</div>
<div className="col-md-5">
<Card title="Some content will come" titleIcon="ion-clipboard">
<p>Content will come.</p>
</Card>
</div>
</div>
</React.Fragment>
);
}
}
export default Home;
You need to tell react that the component is ready to accept children.
React provides a utility for exactly this. Just replace your interface Props {...} with type Props = PropsWithChildren<{...}>.
import { PropsWithChildren } from "react";
type Props = PropsWithChildren<{
user: UserStateInterface;
setUser: typeof setUser;
}>;
Example: https://codesandbox.io/s/boring-chatelet-kp5vm?file=/src/Layout.tsx

Why Inline Styling style={{maxHeight:'443 px', maxWidth: '443 px'}} is not working in component

Tysm for help in advance!
I am doing famous react Course of Coursera!
IN App.js Menu is rendered as Component. MenuComponent.js is as follows:
import React,{Component} from 'react';
import DishDetail from './DishDetail';
import { Card, CardImg, CardImgOverlay} from 'reactstrap';
class Menu extends Component {
constructor(props) {
super(props);
this.state = {
selectedDish: null
}
}
onDishSelect(dish) {
this.setState({ selectedDish: dish});
}
renderDish() {
if (this.state.selectedDish)
return <DishDetail dish={this.state.selectedDish} />;
else
return(
<div></div>
);
}
render() {
const menu = this.props.dishes.map((dish) => {
return (
<Card
key={dish.id}
className="col-12 col-md-5 m-1"
onClick={() => this.onDishSelect(dish)}
>
<CardImg width="100%" className="card-img-top" src={dish.image} alt={dish.name} />
<CardImgOverlay className="card-image-overlay">
<h5>{dish.name}</h5>
</CardImgOverlay>
</Card>
);
});
return (
<div className="container">
<div className="row">
{menu}
</div>
<div className="row">
<div classNmae="col-12 col-md-5 m-1">
{this.renderDish(this.state.selectedDish)}
</div>
</div>
</div>
);
}
}
export default Menu;
DishDetail.js is as follows:
import React, { Component } from 'react';
import { Card, CardImg, CardText, CardBody,CardTitle} from 'reactstrap';
class DishDetail extends Component {
render () {
return (<div className="row">
<div classname="col-6 col-md-4" >
<Card>
<CardImg style={{maxWidth:'443 px', maxHeight:'443 px'}} top src={this.props.dish.image} alt={this.props.dish.name} />
<CardBody>
<CardTitle>{this.props.dish.name}</CardTitle>
<CardText className="text-center">{this.props.dish.description}</CardText>
</CardBody>
</Card>
</div>
<div className="col-6 col-md-4">
<h3>Comments</h3>
{
this.props.dish.comments.map( (comment) => {
return (
<div id={comment.id}>
<p>{comment.comment}</p>
<p>--{comment.author} , {comment.date}</p>
</div>
)
})
}
</div>
</div>
);
}
}
export default DishDetail;
I want render Dish Detail and it's comments in form col-6 col-6 means side by side. But Instead of that, I am getting output like:-
Desired Output is like:
Tysm for solving in advance!
Try to use it this way:
import React, { Component } from 'react';
import { Card, CardImg, CardText, CardBody,CardTitle} from 'reactstrap';
class DishDetail extends Component {
render () {
const myStyle = {
maxWidth:'443px',
maxHeight:'443px'
}
return (<div className="row">
<div classname="col-6 col-md-4" >
<Card>
<CardImg style={myStyle} top src={this.props.dish.image} alt={this.props.dish.name} />
<CardBody>
<CardTitle>{this.props.dish.name}</CardTitle>
<CardText className="text-center">{this.props.dish.description}</CardText>
</CardBody>
</Card>
</div>
<div className="col-6 col-md-4">
<h3>Comments</h3>
{
this.props.dish.comments.map( (comment) => {
return (
<div id={comment.id}>
<p>{comment.comment}</p>
<p>--{comment.author} , {comment.date}</p>
</div>
)
})
}
</div>
</div>
);
}
}
export default DishDetail;
https://www.w3schools.com/react/showreact.asp?filename=demo2_react_css_inline_object
It's a 443px unit, there is no space between 443 and px. Otherwise, the CSS will not be applied to your selected element.
<Card>
<CardImg
style={{ maxWidth: "443px", maxHeight: "443px" }}
top
src={this.props.dish.image}
alt={this.props.dish.name}
/>
<CardBody>
<CardTitle>{this.props.dish.name}</CardTitle>
<CardText className="text-center">{this.props.dish.description}</CardText>
</CardBody>
</Card>
One more example where 10 px (with space) unit will not work.
import React from 'react';
export default class App extends React.Component {
render() {
const mystyle = {
color: "white",
backgroundColor: "DodgerBlue",
padding: "10 px", // check here not applied
fontFamily: "Arial"
};
return (
<div>
<h1 style={mystyle}>Hello Style!</h1>
<p>Add a little style!</p>
</div>
);
}
}
Demo on Sandbox

How to pass a function from a component to another component in react

I have 2 class components in 2 different js files. The "dish" variable is defined in one and I'm trying to use it in the second file. I'm still new to this, so I'm really not sure if I'm structuring this correctly. Could some one help?
First class component
import React, { Component } from "react";
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,
details: Dishdetail
};
}
onDishSelect(dish) {
this.setState({
selectedDish: dish
});
}
renderDish(dish) {
if (dish != null) {
return <Dishdetail details={this.state.details} />;
} else {
return <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.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"> {menu}</div>
<div className="row">
<div className="col-12 col-md-5 m-1">
{this.renderDish(this.state.selectedDish)}{" "}
</div>{" "}
</div>{" "}
</div>
);
}
}
export default Menu;
=======================
Second code
import React, { Component } from "react";
import {
Card,
CardImg,
CardImgOverlay,
CardText,
CardBody,
CardTitle
} from "reactstrap";
import Menu from "./MenuComponent";
class Dishdetail extends Component {
constructor(props) {
super(props);
this.state = {
dish: Menu
};
}
render() {
return (
<div className="container">
<div className="row">
<dish />
<Card>
<CardImg top src={dish.image} alt={dish.name} />
<CardBody>
<CardTitle>{dish.name}</CardTitle>
<CardText>{dish.description}</CardText>
</CardBody>
</Card>
</div>
</div>
);
}
}
export default Dishdetail;
The error message I'm getting is that "dish" variable is not defined
You cannot set props to state in child like this,
this.state = {
dish: Menu
};
As you are passing details as props from parent component you should do this,
constructor(props) {
super(props)
this.state = {
dish: props.details,
}
}
And you should use this state in child component like.
{this.state.dish}
Demo - How to pass data from parent and usage in child component.
Update
Your Code - I have corrected your code. Just make sure you pass correct details to your Menu component.
Note: This code gives you error because I don't know what this.props.dishes is. Ignore the error and concentrate on code only.

Passing function to Component in React

Hi the previous answers to similar Questions doesn't help me.
I have the App Component:
import React from "react";
import Header from "./components/Header";
import Menu from "./components/Menu";
import Board from "./components/Board";
class App extends React.Component {
constructor() {
super();
this.onButtonClick = this.onButtonClick.bind(this);
this.state = {
condition: true
};
}
onButtonClick() {
console.log("clicked...");
this.setState({
condition: !this.state.condition
});
}
render() {
return (
<div className="App">
<Header />
<Menu condition={this.state.condition} />
<Board />
</div>
);
}
}
export default App;
the MenuIcon Component:
import React from "react";
import "../css/main.css";
class MenuIcon extends React.Component {
render() {
return (
<div className="Menu_icon" onClick={this.props.onButtonClick}>
<div className="Menu_icon_element" />
<div className="Menu_icon_element" />
<div className="Menu_icon_element" />
</div>
);
}
}
export default MenuIcon;
and the Menu Component
import React from "react";
import "../css/main.css";
class Menu extends React.Component {
render() {
return (
<div className={this.props.condition ? "Menu inactive" : "Menu active"}>
<ul>
<li>Notes</li>
<li>Erinnerungen</li>
</ul>
</div>
);
}
}
export default Menu;
import React from "react";
import "../css/main.css";
class Menu extends React.Component {
render() {
return (
<div className={this.props.condition ? "Menu inactive" : "Menu active"}>
<ul>
<li>Notes</li>
<li>Erinnerungen</li>
</ul>
</div>
);
}
}
export default Menu;
and the Header Component
import React from "react";
import "../css/main.css";
import MenuIcon from "./MenuIcon";
class Header extends React.Component {
render() {
return (
<div className="Header_container">
<MenuIcon onButtonClick={this.props.onButtonClick} />
<div className="Header_headline">Notes</div>
</div>
);
}
}
export default Header;
I want to trigger the onButtonClick defined in App.js every time when I click on the MenuIcon. And then the Menu should fade in or out. The animation is done with css.
I dont find my mistake?
Could someone please help me?

Why is my component not effectively receiving props?

I keep getting a message that the item I'm trying to access via props is undefined. Can you please tell me why it's not working?
Here is where the instance where the props are attempting to be passed... I'm specifically talking about the tellus and yourTrial props.
import React from 'react'
import Info from './components/Info'
import Upsell from '../../../general/components/order/components/Upsell'
import FormTwo from '../../../general/components/forms/FormTwo'
import Footer from '../../../cbd-desktop/components/layout/Footer'
export default class Order extends React.Component {
render() {
return (
<div>
<div>
<div style={styles.header}>
<img style={styles.leaf} src="./resources/desktop-img/leaves_top.png" />
<img style={styles.logo} src="./resources/desktop-img/logo_white.png" />
</div>
<div style={styles.wrapper}>
<div style={styles.leftWrapper}>
<Info />
<Upsell styles={upsellStyles} />
</div>
<FormTwo styles={formStyles} tellus="Tell us where to send" yourTrial="YOUR TRIAL BOTTLE"} />
</div>
</div>
<Footer style={styles.footer}/>
</div>
)
}
}
And here is where I am trying to display these values on the child... towards the top in two h2s
import React from 'react'
import { connect } from 'react-redux'
import { stepTwoSubmit, saveBillingData } from
'../../actions/formStepTwoActions'
import { addReceiptProduct } from '../../actions/receiptActions'
import FormTwoInputs from './components/FormTwoInputsComponent.jsx'
import Throbber from '../throbber/Throbber'
import FormWarning from './components/FormWarningComponent.jsx'
import Button from '../../../cbd-desktop/components/layout/Button'
const mapStateToProps = state => ({
state:state,
config:state.config,
downsellProduct:state.downsell.downsellProduct || {},
receiptProducts:state.receipt.receiptProducts || []
})
const mapDispatchToProps = {
stepTwoSubmit,
saveBillingData,
addReceiptProduct
}
#connect(mapStateToProps, mapDispatchToProps)
export default class FormTwo extends React.Component {
constructor(props) {
super(props)
componentWillReceiveProps(nextProps) {
let formTwoResponse = nextProps.state.stepTwo.formTwoResponse
this.checkOrderStatus(formTwoResponse)
}
componentDidMount() {
this.fillMainOrder()
this.calculateViewers()
this.calculateTimer()
}
render() {
let { state, props, inputs, onInputFocus, saveInputVal, styles } = this,
CustomTag = props.labels ? 'label' : 'span',
{ submitting, formWarning } = state,
{ invalidInputID, text, visible } = formWarning
return (
<div style={styles.formWrapper}>
<p style={styles.yellowBanner}>{this.state.viewers} people viewing this product right now</p>
<div style={styles.formInnerWrapper}>
<div style={styles.headerWrapper}>
<h2 style={styles.header}>{this.props.tellus}</h2>
<h2 style={styles.header}>{this.props.yourTrial}</h2>
</div>
<div style={styles.weAccept}>
<p style={styles.weAcceptText}>We Accept:</p>
<img style ={styles.cardImage} src="resources/desktop-img/cards.png" />
</div>
<form onSubmit={this.submit}>
<FormTwoInputs onInputFocus={onInputFocus} saveInputVal={saveInputVal} CustomTag={CustomTag} styles={styles} />
<FormWarning visible={visible} invalidInputID={invalidInputID} text={text} />
<Button style={styles.button} buttonText="RUSH MY TRIAL" />
</form>
</div>
<img src="resources/desktop-img/secure.png" />
<div style={styles.urgencyWrapper}>
<div style={styles.urgencyTextWrapper}>
<span style={styles.redText}>{this.state.viewers} people are viewing this offer right now -</span>
<span style={styles.blueText}>{this.state.counter}</span>
</div>
<p style={styles.blueText}>Claim Your Bottle Now</p>
</div>
<Throbber throbberText='Confirming your shipment...' showThrobber={submitting} />
</div>
)
}
}

Resources