when i add product in cart there is nothing displayed in car and "items not found" error is displayed on the screen and when i try to use null check and npm start then error is not shown but still balnk page is displayed.
import React from 'react';
import Header from './Front/Header/Header';
const Cart = ({ cartitems ,handleAddProduct,handleRemoveProduct} ) => {
return (
<>
<Header />
<div className="cart-items">
<div className="cart-items-header"> cartitems</div>
{!cartitems?.length ? (
<div className="cart-items-empty"> No items added in cart</div>
) : null}
<div>
{cartitems?.length ? cartitems.map((item,name ,price ,image ,id) => (
<img
key={item.id}
className="cart-items-image"
src={item.image}
alt={item.name}
/>
)) : null}
</div>
<div>
<h3 className='cart-items-name'>
{item.name}</h3>
</div>
<div className='cart-items-function'>
<button className='cart-items-add' onClick={() =>handleAddProduct(item)}>
+
</button>
<button
className='cart-items-remove' onClick={()=>handleRemoveProduct(item)}>
-
</button>
</div>
<div
className='cart-items-price'>
{item.quantity}* ${item.price}
</div>
</div>
</>
);
}
export default Cart;
I think there are 2 problems in your code :
Firstly, I suppose that each item in your cartitems has the following structure :
item = {
id: 1,
name: "my item",
price: 2,
image: "http://mybeautifulurl.org/image.png"
}
If that is the case, you should pass item as the only argument in the map function, and access each props with item.id, item.name, item.price and item.image.
Some of your code is not in the map function but needs the item, so it cannot display anything.
Here is your updated code :
import React from "react";
import Header from "./Front/Header/Header";
const Cart = ({ cartitems, handleAddProduct, handleRemoveProduct }) => {
return (
<>
<Header />
<div className="cart-items">
<div className="cart-items-header"> cartitems</div>
{!cartitems?.length ? (
<div className="cart-items-empty"> No items added in cart</div>
) : null}
<div>
{cartitems?.length
? cartitems.map((item) => (
<>
<img
key={item.id}
className="cart-items-image"
src={item.image}
alt={item.name}
/>
<div>
<h3 className="cart-items-name">{item.name}</h3>
</div>
<div className="cart-items-function">
<button
className="cart-items-add"
onClick={() => handleAddProduct(item)}
>
+
</button>
<button
className="cart-items-remove"
onClick={() => handleRemoveProduct(item)}
>
-
</button>
</div>
<div className="cart-items-price">
{item.quantity}* ${item.price}
</div>
</>
))
: null}
</div>
</div>
</>
);
};
export default Cart;
Let me know if this solves the problem :)
Related
This question already has answers here:
useRouter/withRouter receive undefined on query in first render
(9 answers)
Closed 5 months ago.
I am using the id gotten from next router.query to render elements dynamically it works when i access the room from next/link but when i refresh the page it throws this error
here is my code (note: roomId here was gotten from const {roomId} = router.query):
return (
<>
<div className={styles.header}>
<div className={styles.title}>{rooms[roomId].name}</div>
<div className={styles.headerCon}>
<div className={styles.roomUsers}>
<AvatarGroup
max={3}
total={Object.keys(rooms[roomId].users).length}
>
{Object.keys(rooms[roomId].users).map((user) => (
<Avatar
key={user + Math.random()}
alt={users[user].name}
src={users[user].profile_pic}
/>
))}
</AvatarGroup>
</div>
<div className={styles.headerIcons}>
<div className={styles.react}>
<AddReactionOutlinedIcon />
</div>
<div className={styles.notif}>
<NotificationsNoneOutlinedIcon />
</div>
<div className={styles.more}>
<MoreHorizOutlined />
</div>
</div>
</div>
</div>
{user.name === rooms[roomId].createdBy.name ? (
<div className={styles.begin}>
{!roomActive ? (
<button onClick={handleStartSession}>Start</button>
) : (
<button onClick={handleEndSession}>End</button>
)}
</div>
) : (
""
)}
<div className={styles.participators}>
<div className={styles.pAvatars}>
<Avatar
alt={rooms[roomId].createdBy.name}
src={rooms[roomId].createdBy.profile_pic}
/>
<div className={styles.userName}>{rooms[roomId].createdBy.name}</div>
<div className={styles.userRole}>Admin</div>
<div>
<audio autoPlay ref={userAudio} />
{peers.map((peer, index) => {
return <Audio key={index} peer={peer} />;
})}
</div>
</div>
{Object.keys(rooms[roomId].users)
.filter((user) => users[user].name !== rooms[roomId].createdBy.name)
.map((user) => (
<div className={styles.pAvatars} key={Math.random() + user}>
<Avatar alt={users[user].name} src={users[user].profile_pic} />
<div className={styles.userName}>{users[user].name}</div>
<div className={styles.userRole}>Admin</div>
</div>
))}
</div>
</>
);
}
As you can see much of what i am rendering on this page depends on that id, so can someone please help?
You try to access the query parameter before its state is ready. There is a workaround to solve this problem.
import { useRouter } from 'next/router';
const router = useRouter();
useEffect(() => {
if (router.isReady) {
// Do your stuff
// for example: assign query param to a state
}
}, [router.isReady]);
I have list of items = exemple1, exemple2, ..... and each one clicked
when I choose one of the list the URL be like :
localhost:3000/portfolio/exemple1
localhost:3000/portfolio/exemple2
how I can do it please?
the list
import { Link } from 'react-router-dom';
export const ListPortfolio = (props) => {
const portfolio = props.portfolio;
const number = props.number;
return(
<div className="d-flex flex-wrap table">
{portfolio.map((item, i) =>
<Link to={{ pathname:"/DetailPortfolio", state:item}} state className="text-black text-decoration-none link" key={item.id} >
<div className="card">
<img src={item.image} alt={item.title} />
<div className="card-body">
<h3 className="card-title">{item.title}</h3>
<span className="url">URL: </span><span>{item.excerpt && item.excerpt.slice(10, -5)}</span>
</div>
</div>
</Link>
)}
</div>
)
}
detailsOfList
const DetailPortfolio = (props) => {
const {state} = props.location
return (
<>
<div className="container-fluid">
<Details>
<div>
<div>{state.title}</div>
<img src={state.image} alt={state.title} />
<div>{state.content}<div/>
</div>
</div>
</Details>
</div>
</>
);
}
happy 2022!
I'm working on adding an onClick event listener/button.
This app it's an Airbnb clone, and I'm working on the SingleRoom page, which displays details about that specific room/home.
Once the user clicks to a particular place, it will redirect to the SingleRoom page (below code) it has a "Reserve now" button so the user can pay for the room/home.
When I try adding the button, I get this error:
Uncaught Error: SingleRoom(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.
The reserve button will open a modal to either cancel or continue to make the payment.
Would you please help me in making the code work?
Thank you
Updated the code.. It now has the else statement
But it throws this error:
Line 29:15: 'setOpenModal' is not defined no-undef
import React, { Component } from "react";
import defaultBcg from "../images/room-1.jpeg";
import Banner from "../components/Banner";
import { Link } from "react-router-dom";
import { RoomContext } from "../context";
import StyledHero from "../components/StyledHero";
import "../components/Modal.css";
export default class SingleRoom extends Component {
constructor(props) {
super(props);
this.state = { slug: this.props.match.params.slug, defaultBcg };
}
static contextType = RoomContext;
render() {
const { getRoom } = this.context;
const room = getRoom(this.state.slug);
if (!room) {
return (
<div className="error">
<h3>Sorry we couldn't find the room you were looking for'...</h3>
<Link to="/rooms" className="btn-primary">
Back to rooms
</Link>
</div>
);
}else{
Modal(setOpenModal);
}
function Modal({ setOpenModal }) {
const {
name,
description,
capacity,
size,
price,
extras,
breakfast,
pets,
images,
} = room;
const [mainImg, ...defaultImg] = images;
return (
<>
<StyledHero img={mainImg || this.state.defaultBcg}>
<Banner title={`${name}`}></Banner>
</StyledHero>
<section className="single-room">
<div className="single-room-images">
{defaultImg.map((item, index) => {
return <img key={index} src={item} alt={name} />;
})}
</div>
<div className="single-room-info">
<article className="desc">
<h3>details</h3>
<p>{description}</p>
</article>
<article className="info">
<h3>Info</h3>
<h6>Price: ${price}</h6>
<h6>Size: ${size} SQFT</h6>
<h6>
Max capacity: {""}
{capacity > 1 ? `${capacity} people` : `${capacity} person`}
</h6>
<h6>{pets ? "pets allowed" : "no pets allowed"}</h6>
<h6>{breakfast && "free breakfast included"}</h6>
<div className="modalBackground">
<div className="modalContainer">
<div className="titleCloseBtn">
<button
onClick={() => {
setOpenModal(false);
}}
>
X
</button>
</div>
<div className="title">
<h1>Reservation details</h1>
</div>
<div className="body">
<p>
Total amount {{price}}
</p>
</div>
<div className="footer">
<button
onClick={() => {
setOpenModal(false);
}}
id="cancelBtn"
>
Cancel
</button>
<button>Reserve Now</button>
</div>
</div>
</div>
</article>
</div>
</section>
<section className="room-extras">
<h6>extras</h6>
<ul className="extras">
{extras.map((item, index) => {
return <li key={index}>- {item}</li>;
})}
</ul>
</section>
</>
);
}
}
}
Because there is no else condition found. Change your code to
render() {
const { getRoom } = this.context;
const room = getRoom(this.state.slug);
if (!room) {
return (
<div className="error">
<h3>Sorry we couldn't find the room you were looking for'...</h3>
<Link to="/rooms" className="btn-primary">
Back to rooms
</Link>
</div>
);
}else{
Modal(setOpenModal);
}
}
function Modal({ setOpenModal }) {
const {
name,
description,
capacity,
size,
price,
extras,
breakfast,
pets,
images,
} = room;
const [mainImg, ...defaultImg] = images;
return (
<>
<StyledHero img={mainImg || this.state.defaultBcg}>
<Banner title={`${name}`}></Banner>
</StyledHero>
<section className="single-room">
<div className="single-room-images">
{defaultImg.map((item, index) => {
return <img key={index} src={item} alt={name} />;
})}
</div>
<div className="single-room-info">
<article className="desc">
<h3>details</h3>
<p>{description}</p>
</article>
<article className="info">
<h3>Info</h3>
<h6>Price: ${price}</h6>
<h6>Size: ${size} SQFT</h6>
<h6>
Max capacity: {""}
{capacity > 1 ? `${capacity} people` : `${capacity} person`}
</h6>
<h6>{pets ? "pets allowed" : "no pets allowed"}</h6>
<h6>{breakfast && "free breakfast included"}</h6>
<div className="modalBackground">
<div className="modalContainer">
<div className="titleCloseBtn">
<button
onClick={() => {
setOpenModal(false);
}}
>
X
</button>
</div>
<div className="title">
<h1>Reservation details</h1>
</div>
<div className="body">
<p>
Total amount {{price}}
</p>
</div>
<div className="footer">
<button
onClick={() => {
setOpenModal(false);
}}
id="cancelBtn"
>
Cancel
</button>
<button>Continue</button>
</div>
</div>
</div>
</article>
</div>
</section>
<section className="room-extras">
<h6>extras</h6>
<ul className="extras">
{extras.map((item, index) => {
return <li key={index}>- {item}</li>;
})}
</ul>
</section>
</>
);
}
My component is being rendered in a single column equal to the photo I attached, but it is wrong, it was to be a 5x4 array.
edi1: In an old version of the code I did not have this problem, however I received some props, and since I have to constantly change the contents of the Component, I thought it was good to use state.
render() {
return (
<div className="App">
<Navbar onChange={this.onChange.bind(this)} />
<div className="container mt-10">
<div className="row">
{<RecipeItem list={this.state.searchString} />}
</div>
</div>
</div>
);
}
}
File RecipeItem.js
const RecipeList = ({ searchString }) => {
return(
<div>
<img className="card-img-top img-fluid" src={searchString.thumbnail} alt={searchString.title} />
<div className="card-body">
<h5 className="card-title">{searchString.title}</h5>
<p className="card-text">
<strong>Ingredients: </strong>{searchString.ingredients}
</p>
</div>
</div>
)
}
const RecipeItem = (props) => {
return (
<div className="col-sm-3 mt-4">
<div className="card">
{props.list && props.list.map((searchString, index) =>
<RecipeList searchString={searchString} key={index} />
)}
</div>
</div>
)
}
You're applying col-sm-3 before iterating on each element, you should apply the class on each iteration like this :
const RecipeItem = (props) => {
return (
props.list && props.list.map((searchString, index) =>
<div className="card col-sm-3 mt-4">
<RecipeList searchString={searchString} key={index} />
</div>
)
)
}
I'm mapping all of my files
_renderItems = files =>
files
? files.map((item, i) => {
return <ProjectItemUser {...item} key={i} index={i} />;
})
: null;
and then I'm trying to display it ProjectItemUser
class ProjectItemUser extends Component {
render() {
return (
<div>
<div className="book_item">
<div className="book_header">
<h2>{this.props.name}</h2>
</div>
<div className="book_this">
<div className="book_author">{this.props.subject}</div>
<div className="book_bubble">
<strong>Study: </strong> {this.props.study}
</div>
<div className="book_bubble">
<strong>Grade: </strong> {this.props.grade}
</div>
<FontAwesomeIcon icon="trash" id="trash" />
</div>
</div>
</div>
);
}
}
This basically displays all the files, and each file is its own separate row. I would like to assign value to div element on each iteration, so I can control which file has been clicked.
I can access my id with: this.props._id
Should this be done using refs and if so, how ?
You should pass onClick function as parameter
_renderItems = files =>
files
? files.map((item, i) => {
return <ProjectItemUser {...item} key={i} index={i} onClick={() => { console.warn(item) } />;
})
: null;
class ProjectItemUser extends Component {
render() {
return (
<div>
<div className="book_item">
<div className="book_header">
<h2>{this.props.name}</h2>
</div>
<div className="book_this">
<div className="book_author">{this.props.subject}</div>
<div className="book_bubble">
<strong>Study: </strong> {this.props.study}
</div>
<div className="book_bubble">
<strong>Grade: </strong> {this.props.grade}
</div>
<FontAwesomeIcon icon="trash" id="trash" />
<Button onClick={this.props.onClick} label="Click on me" />
</div>
</div>
</div>
);
}
}