When I click on react router nothing happen - reactjs

I am working on a list of pokemons app like in this tutorial: https://www.youtube.com/watch?v=XehSJF85F38&t=5904s
But I have problem, for some reason my routes don't work, and I did everything like in tutorial.
Here is my code:
function App() {
return (
<Router>
<div className="App">
<NavBar />
<div className="container">
<Switch>
<Route exact path="/"></Route>
<Route exact path="pokemon/:pokemonIndex" component={Pokemon} />
</Switch>
<Body />
</div>
</div>
</Router>
);
}
And I call it in another component:
render() {
return (
<div className="col-md-4 col-sm-6 mb-3">
<Link to={`pokemon/${this.state.pokemonIndex}`} className="cardLink">
<div className="card cardeffect">
<h5 className="card-header">
{this.state.pokemonIndex}. {this.state.pokemonName.toUpperCase()}
</h5>
{this.state.imageLoading ? (
<img
src={loading}
style={{ width: "6em", height: "6em" }}
className="card-img-top mx-auto mt-2"
/>
) : null}
<div className="card-body mx-auto">
<Sprite
className="card-image-top mx-auto mt-2"
onLoad={() => this.setState({ imageLoading: false })}
onError={() => this.setState({ request: true })}
src={this.state.imageUrl}
style={
this.state.tooManyRequest
? { display: "none" }
: this.state.imageLoading
? { display: "none" }
: { display: "block" }
}
></Sprite>
</div>
</div>
</Link>
</div>
);
}
But when I click on any of cards, URL changes but that is all, nothing more happen.

Ey!
I am not sure but I think Link is not fitted for what you want to do. It's ok to create a link on a navbaritem for instance but not to trigger redirection onclick.
Maybe try to use an onclick event on your card with the Redirect component. Something like this might work:
<div className="card-body mx-auto" onclick={() => {return <Redirect to=`pokemon/${this.state.pokemonIndex}`}>
<Sprite
className="card-image-top mx-auto mt-2"
onLoad={() => this.setState({ imageLoading: false })}
onError={() => this.setState({ request: true })}
src={this.state.imageUrl}
style={
this.state.tooManyRequest
? { display: "none" }
: this.state.imageLoading
? { display: "none" }
: { display: "block" }
}
>
</Sprite>
</div>
You might also be able to trigger the event directly in the Sprite component, Idk this package.
Hopping it will help !

It will be useful for you to do this from the root while defining the route.
function App() {
return (
<Router>
<div className="App">
<NavBar />
<div className="container">
<Switch>
<Route exact path="/"></Route>
<Route path="/pokemon/:pokemonIndex" component={Pokemon} />
</Switch>
<Body />
</div>
</div>
</Router>
);
}
and
render() {
return (
<div className="col-md-4 col-sm-6 mb-3">
<Link to={`/pokemon/${this.state.pokemonIndex}`} className="cardLink">
...
...
</Link>
</div>
);

Related

mapping some images with out key and value pair in react

I have a data like this
const data = ["https://via.placeholder.com/60x60",
"https://via.placeholder.com/60x60",
"https://via.placeholder.com/60x60",
"https://via.placeholder.com/60x60"];
not the pair of key and value.
I want to make it by mapping like,
<div>
<img src={} />
<img src={} />
<img src={} />
<img src={} />
<div>
so coded
<div className="App">
{data.map((item) => {
<img src={item}/>
})}
</div>
but it does not work.
can any one help me?
Without Scope
<div className="App">
{data.map((item, key) => (
<img src={item} key={key} />
))}
</div>
With Scope
<div className="App">
{data.map((item, key) => {
return <img src={item} key={key} />;
})}
</div>

Cannot redirect one page to another page in ReactJs

I'm making a function that when i click on the image container, it will open the page with the product detail with the exact detail for each specific product. However, when i click on the image, nothing happen! Please help me to find out what wrong with my codes, thank you so much!
Product.js:
class Product extends React.Component {
render() {
const { id, title, img, price, inCart } = this.props.product;
return (
<ProductWrapper clasName="col-9 mx-auto col-md-6 col-lg-3 my-3">
<div className="card">
<ProductContext.Consumer>
{(value) => (
<div className="img-container p-5">
<Router>
<Link to="/details">
<img
src={img}
alt="product"
className="card-img-top"
onClick={() => {
value.handleDetail(id);
}}
/>
</Link>
</Router>
<button
className="cart-btn"
onClick={() => value.addToCart(id)}
disabled={inCart ? true : false}
>
{inCart ? (
<p className="text-capitalize mb-0">In Cart</p>
) : (
<i class="fas fa-cart-plus"></i>
)}
</button>
</div>
)}
</ProductContext.Consumer>
<div className="card-footer d-flex justify-content-between">
<p className="align-self-center mb-0">{title}</p>
<h5 className="text-blue mb-0">
<span className="mr-1">$</span>
{price}
</h5>
</div>
</div>
</ProductWrapper>
);
}
}
context.js:
class ProductProvider extends React.Component {
state = {
products: storeProducts,
detailProduct: detailProduct
};
getItem = (id) => {
const product = this.state.products.find((item) => item.id === id);
return product;
};
handleDetail = (id) => {
const product = this.getItem(id);
this.setState(() => {
return { detailProduct: product };
});
};
addToCart = (id) => {
console.log(`hello details. id is ${id}`);
};
render() {
return (
<ProductContext.Provider
value={{
...this.state,
handleDetail: this.handleDetail,
addToCart: this.addToCart
}}
>
{this.props.children}
</ProductContext.Provider>
);
}
}
Sandbox link for better observation: https://codesandbox.io/s/why-cant-i-fetch-data-from-a-passed-value-forked-30bgi?file=/src/App.js
I recommend a different approach where the product ID goes into the URL rather than being selected in context. This has a major advantage in that refreshing the details page means the product ID will be retained.
Here is a link to a working CodeSandbox.
And here are the changes I made:
In the context provider, you can remove handleDetail since the selection will instead live in the URL:
class ProductProvider extends React.Component {
state = {
products: storeProducts,
detailProduct: detailProduct
};
getItem = (id) => {
const product = this.state.products.find((item) => item.id === id);
return product;
};
addToCart = (id) => {
console.log(`hello details. id is ${id}`);
};
render() {
return (
<ProductContext.Provider
value={{
...this.state,
addToCart: this.addToCart
}}
>
{this.props.children}
</ProductContext.Provider>
);
}
}
In the App component, change your details route to take an itemId parameter:
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<ProductProvider>
<Router>
<Switch>
<Route exact path="/productlist" component={ProductList} />
<Route path="/details/:itemId" component={Details} />
<Route path="*" component={() => "404 Not Found"} />
</Switch>
</Router>
</ProductProvider>
</div>
);
}
In your product component, Make the Link point to the details/itemId URL and remove any need to set that ID in context:
class Product extends React.Component {
render() {
const { id, title, img, price, inCart } = this.props.product;
return (
<ProductWrapper clasName="col-9 mx-auto col-md-6 col-lg-3 my-3">
<div className="card">
<ProductContext.Consumer>
{(value) => (
<div className="img-container p-5">
<Link to={`/details/${id}`}>
<img src={img} alt="product" className="card-img-top" />
</Link>
<button
className="cart-btn"
onClick={() => value.addToCart(id)}
disabled={inCart ? true : false}
>
{inCart ? (
<p className="text-capitalize mb-0">In Cart</p>
) : (
<i class="fas fa-cart-plus"></i>
)}
</button>
</div>
)}
</ProductContext.Consumer>
<div className="card-footer d-flex justify-content-between">
<p className="align-self-center mb-0">{title}</p>
<h5 className="text-blue mb-0">
<span className="mr-1">$</span>
{price}
</h5>
</div>
</div>
</ProductWrapper>
);
}
}
Finally, in the Details component, pluck the itemId off of the params and find the right item from your product list in context:
class Details extends React.Component {
render() {
const { itemId } = this.props.match.params;
return (
<ProductContext.Consumer>
{(value) => {
const selected = value.products.find(
(p) => p.id === parseInt(itemId)
);
if (!selected) {
return "Bad product ID: " + itemId;
}
const { id, company, img, info, price, title, inCart } = selected;
return (
<div className="container py-5">
{/* title */}
<div className="row">
<div className="col-10 mx-auto text-center text-slanted text-blue my-5">
<h1>{title}</h1>
</div>
</div>
{/* end of title */}
<div className="row">
<div className="col-10 mx-auto col-md-6 my-3">
<img src={img} className="img-fluid" alt="" />
</div>
{/* prdoduct info */}
<div className="col-10 mx-auto col-md-6 my-3 text-capitalize">
<h1>model : {title}</h1>
<h4 className="text-title text-uppercase text-muted mt-3 mb-2">
made by : <span className="text-uppercase">{company}</span>
</h4>
<h4 className="text-blue">
<strong>
price : <span>$</span>
{price}
</strong>
</h4>
<p className="text-capitalize font-weight-bold mt-3 mb-0">
some info about product :
</p>
<p className="text-muted lead">{info}</p>
{/* buttons */}
<div>
<Link to="/productlist">
<ButtonContainer>back to products</ButtonContainer>
</Link>
<ButtonContainer
cart
disabled={inCart ? true : false}
onClick={() => {
value.addToCart(id);
}}
>
{inCart ? "in cart" : "add to cart"}
</ButtonContainer>
</div>
</div>
</div>
</div>
);
}}
</ProductContext.Consumer>
);
}
}

findDOMNode is deprecated in StrictMode, Reactjs Modal Component

Reactjs shows this error when i open modal that is from another component
"index.js:1 Warning: findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of Modal which is inside StrictMode. Instead, add a ref directly to the element you want to reference."
I've tried alot of other solutions but none of them work in my case
my code file:
class Routes extends Component {
componentDidMount() {
console.log('Component did mount!')
}
loginModalRef = ({ handleShow }) => {
this.showModal = handleShow;
}
onLoginClick = () => {
this.showModal();
}
ShopersModalRef = ({ handleShoperShow }) => {
this.showShoperModal = handleShoperShow;
}
onShopersClick = () => {
this.showShoperModal();
}
//ChargeModalRef = ({ handleChargeShow }) => {
// this.showChargeModal = handleChargeShow;
//}
// onChargeClick = () => {
// this.showChargeModal();
// }
render() {
return (
<div>
{/*<chargeFeeModal ref={this.ChargeModalRef}></chargeFeeModal>*/}
<FormModal ref={this.loginModalRef}></FormModal>
<ShopersModal ref={this.ShopersModalRef}></ShopersModal>
<AppBar position="sticky" className="appbar">
<Toolbar className="NavbarTop">
<div className='row w-100'>
<div className="col-4 LogoOrBack">
<section className="leftBox shopname ml-4">
<Typography className="typography">
{Text}
</Typography>
</section>
</div>
<div className="col-4 centered">
<section className="centerBox">
<Typography className="typography">
<b>Stores</b>
</Typography>
</section>
</div>
<div className="col-4 righted">
<section className="rightBox">
<Typography className="typography">
<Button className="primary btn AccountBtn" onClick={this.onLoginClick}>
<img alt="user account avatar" src={require('../../../assets/images/placeholder_account.png')} className="buttonImage" /> Account
</Button>
<Button className="primary btn" onClick={this.onLoginClick}>
<i className="fa fa-cart-plus cart"></i>
</Button>
</Typography>
</section>
</div>
</div>
</Toolbar>
<Toolbar>
<div className='row w-100'>
<div className='col-lg-4'>
{(() => {
//Javascript for changing buttons
switch (history.location.pathname) {
case "/": return <Button onClick={this.onLoginClick} className="primary postalCodeBtn" >
<img alt="home icon" src={require('../../../assets/images/homeicon.png')} className="buttonImage" /> <b>M4b 146, CA</b> <i className="fa fa-chevron-down downIco"></i>
</Button>;
default: return (
<Button onClick={this.onShopersClick} className="primary postalCodeBtn" >
<img alt="home icon" src={require('../../../assets/images/time.png')} className="buttonImage" /> <b style={{ textTransform: 'capitalize' }}>Shoppers Occupied</b>
</Button>
);
}
})()}
</div>
<div className="col-lg-4 centered p-1 pl-4" >
<div className="searchContainer">
<i className="fa fa-search searchIcon"></i>
<input className="searchBox" type="search" name="search" placeholder="Search Stores" />
</div>
</div>
{TabsShowOrNo}
</div>
</Toolbar>
</AppBar>
<AnimatedSwitch
atEnter={{ opacity: 0 }}
atLeave={{ opacity: 0 }}
atActive={{ opacity: 1 }}
className="switch-wrapper"
>
<Route exact path="/" component={HomePage} />
<Route path='/store/orders/' component={OrdersPage} />
<Route path='/store/aisles/' component={AislesPage} />
<Route path="/store/featured" component={SingleStorePage} />
<Route component={NotFound} />
</AnimatedSwitch>
</div >
)
}
}```
any help will be appreciate

Cannot read property 'image_url' of undefined in React

I am very new to react and I am trying to show data
but I am getting the error
No Data is appear when i add some code about image_url, title,source_url etc....
TypeError: Cannot read property 'image_url' of undefined
In Recipe.js,
import React, { Component } from 'react'
export default class Recipe extends Component {
render() {
const {
image_url,
title,
source_url,
publisher,
recipe_id
} = this.props.recipe;
return (
<React.Fragment>
<h1>Recipe</h1>
<div className="col-10 mx-auto col-md-6 col-lg-4">
<div className="card">
<img src={image_url} className="img-card-top" style={{height:"14rem"}} alt="recipe" />
<div className="card-body text-capitalize">
<h5>{title}</h5>
<h6 className="text-warning text-slanted">
provided by {publisher}
</h6>
</div>
<div className="card-footer">
<button type="button" className="btn btn-outline-primary">Details</button>
Recipe url
</div>
</div>
</div>
</React.Fragment>
);
}
}
In ReactList.js,
<div className="row">
{recipes.map (recipe => {
return <Recipe key={recipe.recipe_id} recipe={recipe}
/>;
})}
</div>
</div>
<Recipe />
</React.Fragment>
error occur as you use two time <Recipe /> in RecipeList.js,
Removed one <Recipe />,
error will solve
Change
<div className="row">
{recipes.map (recipe => {
return <Recipe key={recipe.recipe_id} recipe={recipe}
/>;
})}
</div>
</div>
<Recipe />
</React.Fragment>
To
<div className="row">
{recipes.map (recipe => {
return <Recipe key={recipe.recipe_id} recipe={recipe}
/>;
})}
</div>
</div>
</React.Fragment>

I had a question about passing id into my route of details when clicked

So once I click on the details page I would like to pass the id of the product to the url when you click it. So when i click the details page I would like for it to be myurl/details/itemid i found this StackOverflow answer but i cant seem to get it to work. React Router Pass Param to Component.
I would like for when my details page reloads it reloads withe correct items id.
this is my details page
import React, { Component } from "react";
import { ProductConsumer } from "../context";
import { Link } from "react-router-dom";
import { ButtonContainer } from "./Button";
import DropDown from "./Dropdown";
import ItemCategory from "./ItemCategory";
import { Carousel } from "react-responsive-carousel";
import "react-responsive-carousel/lib/styles/carousel.min.css";
import { AwesomeButton } from "react-awesome-button";
export default class Details extends Component {
constructor(props) {
super(props);
this.toggle = this.toggle.bind(this);
this.state = {
dropdownOpen: false
};
}
toggle() {
this.setState(prevState => ({
dropdownOpen: !prevState.dropdownOpen
}));
}
render() {
return (
return (
<div className="container-fluid width-100 bg-white py-5 mt-5 ">
{/* ProductInfo */}
<div className="row">
<div className="col mx-auto col-md-6 my-3 ">
<Carousel autoPlay>
<div>
<img src={img} className="img-fluid" alt="product" />
</div>
<div>
<img src={img2} className="img-fluid" alt="product" />
</div>
<div>
<img src={img3} className="img-fluid" alt="product" />
</div>
<div>
<img src={img4} className="img-fluid" alt="product" />
</div>
</Carousel>
{/* Add a Second Image */}
</div>
{/* Product Text */}
<div className="col mx-auto col-md-6 my-3 text-capitalize">
<h1 className="display-3">{title}</h1>
<h4 className="text-black">
<strong className="text-black">
price : <span>$</span>
{price}
</strong>
</h4>
<h4 className="text-blue">
</h4>
<p className="text-black ">{info}</p>
<p className="text-black ">{fabric}</p>
<small className="text-danger">{luxury}</small>
{/* buttons */}
<div>
<Link to="/all">
<AwesomeButton
className="text-capitalize mx-10"
ripple
size="large"
type="primary"
>
Back To Products
</AwesomeButton>
</Link>
<div className="mt-2">
<AwesomeButton
className="text-capitalize m-auto"
ripple
size="medium"
type="primary"
cart
disabled={inCart ? true : false}
onPress={() => {
value.addToCart(id);
}}
>
{inCart ? "inCart" : "add to cart"}
</AwesomeButton>
</div>
<ItemCategory title={category} />
<div className="mt-2">
<img
src="https://www.paypalobjects.com/digitalassets/c/website/marketing/na/us/logo-center/9_bdg_secured_by_pp_2line.png"
border="0"
alt="Secured by PayPal"
/>
</div>
</div>
</div>
</div>
</div>
);
}}
</ProductConsumer>
);
}
}
<Route path="/details/:id" component={Details} />
and in the component Details you have access
export default class Details extends Component {
render() {
return(
<div>
<h2>{this.props.match.params.id}</h2>
</div>
)
}
}

Resources