I have my Parent App.js file where I have two child components, Products, and Cart. I am trying to pass my cart property to child Cart.js but haven't been successful.
App.js
import React,{useState} from 'react';
import {
Route,
BrowserRouter as Router,
} from 'react-router-dom';
import Cart from './components/Cart';
import Product from './components/Product';
function App() {
const [cart, setCart]= useState([]);
const addToCart=(product)=>{
console.log("addToCart button clicked",product)
setCart([...cart, {...product}])
}
return (
<Router>
<Route path="/home/"
render ={()=> < Product addToCart={addToCart}/>}
/>
<Route path="/cart/"
render ={()=> < Cart cart={cart} />}
/>
<div className="App">
</div>
</Router>
);
}
export default App;
Cart.js
import React from 'react'
export default function Cart({cart}) {
return (
<div >
hello
<div className="products" >
{cart.map((product, idx)=>(
<div key={idx}>
<h3>{product.name}</h3>
<h4>{product.cost}</h4>
<img src={product.image} alt = {product.name} />
</div>
))}
</div>
<div>
</div>
</div>
)
}
Product.js
import React,{useState} from 'react';
export default function Product({addToCart}) {
const [products]=useState([
{
name: 'iPhone',
cost : '$899.99',
image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQB6BMWrPXA9KyTtxa6o600mjeUNJ7zSXgaNt--FDCR6YjQ4XWS5G1J3dSF5ChurfQEGxorkxYs&usqp=CAc',
},
{
name: 'Samsung',
cost : '$599.99',
image: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQUGMCcF3_XBIKH5Dja-9iCkRP4CSA-CYaylQ&usqp=CAU'
}
])
return(
<div className="main-page">
<h1>Product Page </h1>
<div className="products" >
{products.map((product, idx)=>(
<div key={idx}>
<h3>{product.name}</h3>
<h4>{product.cost}</h4>
<img src={product.image} alt = {product.name} />
<button onClick={()=>addToCart(product)}
>Add to Cart</button>
</div>
))}
</div>
<div>
</div>
</div>
)
}
localhost:3000/ shows all the products but when I go to localhost:3000/cart/ I don't see my cart items. The mistake I am making I think is in the Route.
<Route path="/cart/"
render ={()=> < Cart cart={cart} />}
/>
How should I pass the cart variable from App.js to Cart.js ?
Related
This question already has answers here:
How to pass data from a page to another page using react router
(5 answers)
Closed 5 months ago.
I am creating an e-commerce website, I want to make a feature, where if the user clicks on a particular product, the user should be able to see the product details of that particular product. I want to implement this in react js with react-router dom, how should I pass the id and show the details of the particular product
Product.jsx
import React, { useState } from 'react'
// import Button from '#mui/material/Button';
import HotelData from "../src/HotelData.json"
import Icons from './components/Icons';
import Subscribe from '../src/components/Subscribe.jsx';
import { Link } from 'react-router-dom';
const Hotel = () => {
return (
<>
<section className='product'>
<div className='container'>
<div className='row'>
{HotelData.product.map((value) => {
return (
<React.Fragment key={value.id}>
<div className='col-xl-3 col-lg-4 col-md-6 col-sm-6 col-12 '>
<div className='cards'>
<Link data-item-id={value.id} to={`/product/${value.id}`} >
<img src={value.img} alt="" />
</Link>
<div className='product-img-badges'>
<span className='pink'>{value.discount}</span>
<span className='purple'>{value.type}</span>
</div>
<div className='description'>
<div className='product-content-3'>
<p>{value.Text}</p>
<h6>{value.price} <del>{value['del-price']}</del></h6>
<div className="icon">
<Icons />
</div>
{/* <Button variant="contained">Contained</Button> */}
</div>
</div>
</div>
</div>
</React.Fragment>
)
})}
</div>
</div>
</section>
<Subscribe />
</>
)
}
export default Hotel
ProductDetails.jsx
import React, { useState } from 'react'
import HotelData from '../HotelData.json'
import Rating from '#mui/material/Rating';
import Stack from '#mui/material/Stack';
import Addcart from './Addcart';
import FacebookIcon from '#mui/icons-material/Facebook';
import SportsVolleyballIcon from '#mui/icons-material/SportsVolleyball';
import PinterestIcon from '#mui/icons-material/Pinterest';
import TwitterIcon from '#mui/icons-material/Twitter';
import LinkedInIcon from '#mui/icons-material/LinkedIn';
const ProductDetails = () => {
return (
<>
<section className='product_details'>
<div className=' container'>
<div className='row'>
<div className='top'>
Home
<span> /</span>
<span to="product">SHOP PRODUCT</span>
</div>
{HotelData.productdetails.map((value) => {
return (
<React.Fragment key={value.id}>
<div className='d-flex gap-5 align-items-center'>
<div className='img'>
<img data-itemID={value.id} className='default-img' src={value.img} alt="" />
</div>
<div className='details'>
<h6>{value.Text}</h6>
<p>{value.price} <span>{value.delprice}</span></p>
<Stack spacing={1}>
<Rating name="half-rating" defaultValue={3} precision={0.5} />
</Stack>
<div className='del'>
<p>{value.details}</p>
</div>
<div className='add_cart'>
<Addcart />
</div>
<div className='categories'>
<h6>{value.cat}</h6>
<h6>{value.tag}</h6>
</div>
<div className='product-icon'>
<ul>
<li><FacebookIcon></FacebookIcon></li>
<li><SportsVolleyballIcon></SportsVolleyballIcon></li>
<li><PinterestIcon></PinterestIcon></li>
<li><TwitterIcon></TwitterIcon></li>
<li><LinkedInIcon></LinkedInIcon></li>
</ul>
</div>
</div>
</div>
</React.Fragment>
)
})}
</div>
</div>
</section>
</>
)
}
export default ProductDetails
App.js
import React from 'react';
import '../src/css/style.css'
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import NavbarMain from './components/Navbar';
import Home from './pages/Home';
import About from './pages/About';
import Collection from './pages/Collection';
import Blog from './pages/Blog';
import Contact from './pages/Contact';
import { Route, Routes } from 'react-router-dom';
// import Footer from './components/Footer';
import Footernew from './components/Footernew';
import ProductDetails from './components/Product-Details';
// import Loader from './components/Loader';
function App() {
return (
<>
{/* <Loader /> */}
<NavbarMain />
<Routes>
<Route exact path='/' element={<Home />} />
<Route exact path='/Home' element={<Home />} />
<Route exact path='/about' element={<About />} />
<Route exact path='/collection' element={<Collection />} />
<Route exact path='/product/' element={<ProductDetails />} />
<Route exact path='/blog' element={<Blog />} />
<Route exact path='/contact' element={<Contact />} />
</Routes>
<Footernew />
</>
);
}
export default App;
This are some screenshot
Here you can see we can see the id after hovering the product
But we cannot get the details of a particular product id after clicking on the product
How can I show the details of a single product on another page? Pls help me I am stuck on this issue
You can check out the example here: https://codesandbox.io/s/react-router-product-detail-pages-dynamic-links-tmcjc
It's simply
<Route exact path='/product/:productId' element={<ProductDetails />} />
I'm making shopping page with React.
I want to go detail page when i click a goods image.
I was trying to get goods's id that clicked to me by <Link className='product-link' to={/goods/${id}}> this code in GoodsList code.
and then, In GoodsDetail code, i was trying to get goods's id that cliked to me and to render the goods's data
But it seems that the in the GoodsList code doesn't work well.
when i click the goods image, page doesn't go to goods/{id}, but go to goods/undefined.
How can i fix my code?
This is App.js code
import React from 'react';
import './App.css';
import Navbar from './components/Navbar';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './pages';
import Sell from './pages/sell';
import Search from './pages/search';
import AboutMe from './pages/aboutme';
import Login from './pages/login';
import TradeRecord from './pages/traderecord';
import SignUp from './pages/signup';
import Zzim from './pages/zzim';
import Selling from './pages/selling';
import Goods from './pages/goods';
const App = () => {
return (
<div className='App'>
<BrowserRouter>
<Navbar />
<Routes>
<Route path="/" element={<Home />}></Route>
<Route path="/sell" element={<Sell />}></Route>
<Route path="/search" element={<Search />}></Route>
<Route path="/signup" element={<SignUp />}></Route>
<Route path="/login" element={<Login />}></Route>
<Route path="/aboutme" element={<AboutMe />}></Route>
<Route path="/selling" element={<Selling />}></Route>
<Route path="/zzim" element={<Zzim />}></Route>
<Route path="/traderecord" element={<TradeRecord />}></Route>
<Route path="/goods/:id" element={<Goods />}></Route>
</Routes>
</BrowserRouter>
</div>
)
}
export default App;
This is Goods List page code
import React, {useState, useEffect} from 'react';
import { Link, useParams } from 'react-router-dom';
import axios from 'axios';
import './index.css';
const SearchView = (props) => {
const [boards, setBoards] = useState([]);
const {id} = useParams();
useEffect(() => {
(async function () {
const response = await axios.get("https://27.96.131.85:8443/api/boards")
.catch((err) => {
console.log(err);
});
const boards = response.data;
setBoards(boards);
console.log(response.data);
})();
}, []);
return(
<div>
<hr />
<div id='product-list'>
{
boards.map(function(boards, index){
return (
<div className='product-card'>
<Link className='product-link' to={`/goods/${id}`}>
<div>
{
boards.boardImages[0]
? <img className="product-img" width="100" height="100"
src={`https://27.96.131.85:8443/api/images/${boards?.boardImages[0]?.id}`} />
: <img className="product-img" width="100" height="100" src={require("../../images/noImage.png")} />
}
</div>
<div className='product-contents'>
<span className='product-name'>
{boards.goodsName}
</span>
<span className='product-price'>
{boards.price}원
</span>
<div className='product-seller'>
<span>{boards.writer}</span>
</div>
</div>
</Link>
</div>
)
})
}
</div>
</div>
);
};
export default SearchView;
This is Goods detail code
import { useParams } from "react-router-dom";
import axios from "axios";
import { useEffect, useState } from "react";
const Goods = (props) => {
const [boards, setBoards] = useState({});
const [images, setImages] = useState([]);
const {id} = useParams();
useEffect(() => {
(async function () {
const response = await axios.get(`https://27.96.131.85:8443/api/boards/${id}`, {
withCredentials: true,
});
const boards = response.data;
const images = boards.boardImages;
console.log(response.data);
setBoards(boards);
setImages(images);
})();
}, []);
return(
<div id="product">
상품명: <span className="product-name">{boards.goodsName}</span>
<br />
가격: <span className="product-price">{boards.price}원</span>
<div className="product-seller">
작성자: <span>{boards.writer}</span>
</div>
<div className="product-isSale">
판매여부: <span>{boards.sale?.toString()}</span>
</div>
<div className="product-isLiked">
찜 여부: <span>{boards.liked?.toString()}</span>
</div>
<div className="product-atCreated">
작성 시간: <span>{boards.createdDateTime}</span>
</div>
<div className="product-atModified">
수정 시간: <span>{boards.modifiedDateTime}</span>
</div>
<div className="product-images">
{
images.map((image) => {
return (
<img className="product-img" width="100" height="100"
src={`https://27.96.131.85:8443/api/images/${id}`} />
)
})
}
</div>
</div>
);
};
export default Goods;
There is a mistake in your goods list page code,
solution:
{boards.map(function (boards, index) {
return (
<div className="product-card">
<Link className="product-link" to={`/goods/${boards.id}`}>
<div>
{boards.boardImages[0] ? (
<img
className="product-img"
width="100"
height="100"
src={`https://27.96.131.85:8443/api/images/${boards?.boardImages[0]?.id}`}
/>
) : (
<img
className="product-img"
width="100"
height="100"
src={require("../../images/noImage.png")}
/>
)}
</div>
<div className="product-contents">
<span className="product-name">{boards.goodsName}</span>
<span className="product-price">{boards.price}원</span>
<div className="product-seller">
<span>{boards.writer}</span>
</div>
</div>
</Link>
</div>
);
})}
as you used the map function to iterate over the boards array,
and you've assigned variable name 'boards' to each element of the array
so the variable boards itself is an object that contains the id property.
so you have to write boards.id to fix your issue
I hope this might help you
I think it should be boards.id, instead of id..
<Link className='product-link' to={`/goods/${id}`}>
Can you please share your data structure?
For this project, I am following a tutorial. I am a beginner.
My code is throwing an error at
console.log(props.match.params.id);
This is the error
'match.params.id' is missing in props validation
If I change it to console.log(props), it prints {}, which is empty?
What I want it to do is print the id of the product page, in this case it would be 2. "http://localhost:3000/product/2" How can I get this to work?
Here is my full ProductScreen.js
import React from 'react';
function ProductScreen(props) {
console.log(props.match.params.id);
return <div>ProductScreen</div>
}
export default ProductScreen;
And here is app.js with my HTML in it
import React from 'react';
import {BrowserRouter, Routes, Route, Link} from 'react-router-dom';
import './App.css';
import HomeScreen from './Screens/HomeScreen';
import ProductScreen from './Screens/ProductScreen';
function App() {
const openMenu = () =>{
document.querySelector(".sidebar").classList.add("open");
}
const closeMenu = () =>{
document.querySelector(".sidebar").classList.remove("open");
}
return (
<BrowserRouter>
<div className="grid-container">
<header className="header">
<div className="brand">
<button onClick={openMenu}>
☰
</button>
<Link to="/" >E-Commerce</Link>
</div>
<div className="header-links">
Sign In
Cart
</div>
</header>
<aside className="sidebar">
<h3>Shopping Categories</h3>
<button className="sidebar-close-button" onClick={closeMenu}>x</button>
<ul>
<li>
Pants
</li>
<li>
Shirts
</li>
</ul>
</aside>
<main className="main">
<div className="content">
<Routes>
<Route exact path="/" element={<HomeScreen />} />
<Route path="/product/:id" element={<ProductScreen/>} />
</Routes>
</div>
</main>
<footer className="footer">
All rights reserved.
</footer>
</div>
</BrowserRouter>
);
}
export default App;
I'm sorry if that's too much or too little information, this is my first post here.
You aren't passing any props to the ProductScreen component, do this instead
import React from 'react';
import { useParams } from "react-router-dom";
function ProductScreen(props) {
// console.log(props.match.params.id);
const { id } = useParams();
console.log(id);
return <div>ProductScreen</div>
}
export default ProductScreen;
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} />
I am using Preact. I first tried preact-router then wouter for routing, but the problem still exists for one specific component. Here is the main entry where all routes defined:
import { h, Component } from 'preact';
import { Route } from "wouter-preact";
import Header from './partials/header';
import Home from './pages/home';
import News from './pages/news';
import Article from './pages/article';
export default class App extends Component {
render() {
return (
<div id="app">
<Header />
<Route path="/"><Home /> </Route> // working perfectly
<Route path="/a/:article"> <Article /> </Route> // not working
<Route path="/n/:newspaper"><News /> </Route> // working
</div>
);
}
}
and here is the simplified second component which is working perfectly :
import { h, Fragment } from 'preact';
import { Link, Route } from "wouter-preact";
import useFetch from '../../utils/ajax';
export default function News() {
const url = window.location.pathname.split('/');
const { data, loading } = useFetch(domain + '/api/v1/news/?newspaper=' + url[2]);
return (
<Fragment>
{loading ? (
// loading indicator
) : (
<main role="main">
<div className="py-5">
<div className="container">
<div className="row">
{data.results.map((nisha, index) => (
<div className="col-sm-6" key={index}>
<div className="col-md-10" >
<div className="card mb-2 shadow-lg" style={{ border: 'none' }} >
<Link href={'/a/' + nisha.slug}>
<img className="card-img-top" src={ nisha.cover_image } alt={ nisha.slug } />
</Link>
<div className="card-body">
// body
<div className="card-footer text-muted">
// footer
</div>
</div>
</div>
</div>
</div>
))}
</div>
</div>
</div>
</main>
)}
</Fragment>
);
}
and finally the problematic component, when I click any link from previous component, browser url changing but the component is not loading (there is no debug console message in browser console).
export default function Article() {
console.log("loaded");
return (
<div className="main">
<div className="py-5">
<div className="column">
<div>example article</div>
</div>
</div>
</div>
);
}