Click on card then navigate to card page details in react - reactjs

I created a page and show some card also some little details of cards
Now I want to click on any card navigate to this on show all details
How can I get to this page on react js ?
Is this need to Redux ?

I couldn't understand what you said completely, but you can use React-Router to navigate to different pages in Reactjs. To install it using npm, go to your Application directory and enter in command line npm install --save React-Router
Here is a simple code to navigate to different pages:
import React from "react";
import "./App.css";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
const Home=()=>
(<div>
<h2>Home</h2>
</div>
);
const About=()=>
(<div>
<h2>About</h2>
</div>
);
class App extends React.Component {
render() {
return (
<Router>
<div>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<Route exact path="/" component={Home}/>
<Route exact path="/about" component={About}/>
</div>
</Router>
);
}
}
export default App;
I hope it helped...

No need of Redux for your issue.
You just use React-router. you just create two component 1. Cards.js, 2. CardDetails.js and navigate to card details on click event of cards in Card.js
Cards.js
import React from "react";
import { withRouter } from "react-router";
class Cards extends React.Component {
goToCarddetails = (cardId) => {
localStorage.setItem("selectedCard", cardId);
this.props.history.push('/card-details');
// you can manage here to pass the clicked card id to the card details page if needed
}
render() {
return ( <div>
<div onClick = {()=>this.goToCarddetails('cardId1')}> card 1 </div>
<div onClick = {()=>this.goToCarddetails('cardId2')}> card 2 </div>
<div onClick = {()=>this.goToCarddetails('cardId3')}> card 3 </div>
</div>
)
}
}
export default withRouter(Cards);
With above on clicking any card you will be navigated to card details page.
CardDetails.js
import React from "react";
class CardDetails extends React.Component {
render() {
let selectedCardId = localStorage.getItem("selectedCard");
// you can get this cardId anywhere in the component as per your requirement
return ( <div>
card details here
</div>
)
}
}
export default CardDetails;
Note : I'm using react-router 4 here in example.

Related

React router, link to component and show in url

I have a demo here
Its a simple react app using react-router-dom to link to two pages, Home and Info
On the Info page I have two further links.
I would like these links to load components below the links on this page, is this possible with react-router.
Also is it possible to add this link to the url so it would be something like /info/infolinkone
Is this the best way to do this ore does react do it another way.
import React from "react";
import {Link} from 'react-router-dom'
const Info:React.FC = () => {
return (
<div>
<h2>Info</h2>
<ul>
<li><Link>Info Link One</Link></li>
<li><Link>Info Link Two</Link></li>
</ul>
<div>
//Load components here
</div>
</div>
);
};
export default Info;
let me know if this can help you
import React from "react";
import { Link, Route, useRouteMatch } from "react-router-dom";
const Info: React.FC = () => {
let { path, url } = useRouteMatch();
return (
<div>
<h2>Info</h2>
<ul>
<li>
<Link to={`${path}/linkone`}>Info Link One</Link>
</li>
<li>
<Link>Info Link Two</Link>
</li>
</ul>
<div>
<Route exact path={`${path}/linkone`}>
//here you load your component
</Route>
</div>
</div>
);
};
export default Info;

React Link doesn't refresh page automatically

I am currently experiencing an issue similar to React Link doesn't refresh the page, however, the answer doesn't work well for my case.
See, I am currently using react-router to have a path called 'study/:id'. This :id variable will just be printed on the page
Here is the code for my BrowserRouter (App.js)
import React from 'react';
import './App.css';
import HomePage from './HomePage/HomePage';
import Study from './StudyPage/Study';
import {BrowserRouter as Router, Route, Switch } from 'react-router-dom';
function App() {
return (
<Router>
<Switch>
<Route path="/" exact={true} component={HomePage}/>
<Route path="/Study/:id" exact={true} component={Study} />
</Switch>
</Router>
);
}
export default App;
Inside the Study component itself, it basically just has a menubar and an indicator on which courseId are we in:
import React from 'react';
import './Study.css';
import Menubar from '../Menubar';
import Sidebar from './Sidebar';
import Chapter from './Chapter';
class Study extends React.Component{
constructor(props){
super(props);
this.state = {
courseId: this.props.match.params.id,
};
}
render(){
return(
<div id="studyWrapper">
<Menubar />
<h1>We are on course: {this.state.courseId}</h1>
</div>
)
}
}
export default Study;
In order for the user to navigate through the study pages, I use a menubar component like this (Menubar.js)
import React from 'react';
import './Menubar.css';
import { Nav } from 'reactstrap';
import { Dropdown, DropdownButton } from 'react-bootstrap';
import { Link } from 'react-router-dom';
class Menubar extends React.Component{
constructor(props){
super();
this.state = {
courses: [],
reload: false
}
}
async componentDidMount(){
const response = await fetch("/v1/courses/")
const body = await response.json();
this.setState({
courses: body
});
}
render(){
const {courses} = this.state
return (
<Nav className="navbar navbar-expand-md navbar-light menubarStyle fixed-top">
<div className="container-fluid">
<a className="navbar-brand logo" href="/">LOGO</a>
<div className="navbar-collapse">
<div className="navbar-nav">
<div className="dropdown nav-item">
<DropdownButton variant='Secondary' id="dropdown-basic-button" title="Browse Courses">
<Dropdown.Item as={Link} to={`/study/001`} >001</Dropdown.Item>
<Dropdown.Item as={Link} to={`/study/002`} >002</Dropdown.Item>
<Dropdown.Item as={Link} to={`/study/003`} >003</Dropdown.Item>
</DropdownButton>
</div>
</div>
</div>
</div>
</Nav>
)
}
}
export default Menubar
IRL, the study page basically looks like this
The problem
The problem that I am having is that, once I am in '/study/001' page already (just like the picture above). If I try to click on DropdownItem 002 from the menuBar, the URL will change to 'study/002', but the page won't change. It will not refresh.
The solution from React Link doesn't refresh the page basically says to use windows.location.reload() but that doesn't work in my case, if we do that, when I click on dropdownItem 002, the URL will change to 'study/002' for a moment, but then 'study/001' will refresh thus making the page back to 001
My question is, is there a way for us to refresh the page whenever the url is changed by link ?
Or if not, are there any other methods that I can use for this design? Maybe using links is not the right way in the first place?
Pardon the long post, I try to make it as clear as possible.
Thank you !
Inside your Study component you could use componentDidUpdate and compare the current props with the prevProps to check if the url has changed and then change the state, which should cause your component to update. More or less you would have this code:
componentDidUpdate(prevProps) {
if( this.props.match.params.id !== prevProps.match.params.id ){
this.setState({ courseId: this.props.match.params.id })
};
}

Problem with the id of the items in shopping cart application in react

I am developing a shopping cart application . I am using redux and routing . There are mainly 3 pages Home,shop and About. I am adding authentication to the shop page and after successful authentication the user can enter into the shop page. In the shop page there are items which we can add to cart . totally i have 3 items in my shop page.whats my problem is when i am clicking add to cart for 1 st item it is displaying 3 items. I know the problem is with the id's of the items. But I am struggling from past one hour to resolve it.
Thanks in advance.
//App.js
import React ,{Component} from 'react';
import './App.css';
import Navigation from './Step1/Navbar'
import Home from './Step1/Home'
import Shop from './Step1/Shop'
import About from './Step1/About'
import Login from './LoginAuthentication/Loginform'
import {BrowserRouter as Router,Route} from 'react-router-dom'
import {connect} from 'react-redux'
const mapStateToProps=(state)=>{
return{
isLogin:state.isLogin
}
}
class App extends Component {
render(){
return (
<Router>
<div className="App">
<Navigation/>
<Route path="/" exact component={Home}/>
<Route path="/about" component={About}/>
<Route path="/shop"
render={() =>(
this.props.isLogin ? <Shop/> : <Login/>
) }
/>
</div>
</Router>
);
}
}
export default connect(mapStateToProps,null)(App);
//shop template.js
import React from 'react'
//import logo from '../cricket bat.jpg'
import Displaylist from '../Components/DisplayList'
const Shop_template=(props)=> {
return (
<div className="container">
<div className="row">
<div className="col-sm-6">
<div className="card-body">
<h4 className="card-title">{props.cardtitle}</h4>
<p className="card-text">{props.description}</p>
<h3>Price :{props.currency}{props.price}</h3>
<button type="button" onClick={props.cartHandler} className="btn btn-primary">Add to cart</button>
</div>
</div>
<div className="col-sm-6">
<Displaylist/>
</div>
</div>
</div>
)
}
export default Shop_template
//shop.js --> i am updating the state in shop.js to redux state
import React, { Component } from 'react'
import ShopTemplate from './Shop_template'
import {connect} from 'react-redux'
import {action2} from '../Actions/action1'
const mapDispatchToProps=(dispatch)=>({
CartHandler:(details)=>dispatch(action2(details))
})
class Shop extends Component {
state={
items:[
{id:1,cardtitle:'SSS Bat',description:'A stroke to score',currency:'$',price:100},
{id:2,cardtitle:'One upon a wall street',description:'A way to investment',currency:'$',price:50},
{id:3,cardtitle:'mi powerbank 10000mah',description:'Keep charged always',currency:'$',price:200}
]
}
cartHandler=()=>{
this.props.CartHandler(this.state.items)
}
render() {
const info=this.state.items.map((detail)=>{
return <ShopTemplate
cardtitle={detail.cardtitle}
description={detail.description}
currency={detail.currency}
price={detail.price}
key={detail.id}
cartHandler={this.cartHandler}
/>
})
return (
<div>
{info}
</div>
)
}
}
export default connect(null,mapDispatchToProps)(Shop)
/
/reducer.js
import {LOGINCHECK} from '../Constants/actiontypes'
import {ADDTOCART} from '../Constants/actiontypes'
const initialState={
isLogin:false,
items:[]
}
const reducer1=(state=initialState,action)=>{
//console.log(state)
if(action.type===LOGINCHECK){
return Object.assign({},state,{isLogin:true})
}
if(action.type===ADDTOCART){
return Object.assign({},state,{items:state.items.concat(action.payload)})
}
return state
}
export default reducer1
//DisplayList.js
import React from 'react'
import Display from './Display'
import {connect} from 'react-redux'
const mapStateToProps=(state)=>{
return{
items:state.items
}
}
const DisplayList=({items})=>{
console.log(items.body)
return(
<div>
{items.map(it=>{
return(
<Display iteminfo={it.body} key={it.body.id}/>
)
})
}
</div>
)
}
export default connect(mapStateToProps,null)(DisplayList)
//Display.js
import React from 'react'
const Display=({iteminfo:{id,cardtitle, description,currency,price}}) =>{
return (
<div>
<h4>{cardtitle}</h4>
<p>{description}</p>
<h3>{currency}{price}</h3>
<button type="button" className="btn btn-danger">Remove From cart</button>
</div>
)
}
export default Display
I can see too many problems in your source code,
first of all, namings can be better now it's confusing.
your shop items are in Shop component state but it has to be inside your redux module
initialState = {
items: ["your items should be here"]
}
of course, its because you are hardcoding your shop items. you may want to Get shop items from an API.
when you click on add to cart button you have to pass itemId to action. (right now you don't know which item is going to add to cart ).
and then inside reducer action.payload.itemId will be itemId that is added to cart then you can do something like this
const foundItem = state.items.find(it => it.id === action.payload.itemId);
now you found item in your products(items) array,
you can add this item to another array called basket or cart that represents items user added.
for the next step you want to add an inventory and quantity property to see how many items the user wants and how many do you have in your inventory
if you want a more detailed description don't hesitate to ask

React-router custom prop not passing to component. ternary operator not working correctly

In React i have my App.js page where i keep my states. I'm importing user1.js component to App.js, and in user1.js component i have a link button that takes me to path /user2.
When i click the button, React will set state property called testValue to true and in user2.js page ternary operator should choose the first value - test works because of that. But for some reason it does not work.
Any help?
APP.JS
import React, { Component } from 'react';
import './App.css';
import User1 from './components/user1';
class App extends Component {
constructor(props){
super(props);
this.state = {
testValue:false
};
}
change = () => {
this.setState({
testValue:true
},() => {
console.log(this.state.testValue)
});
}
render() {
return (
<div className="App">
<User1 change={this.change}/>
</div>
);
}
}
export default App;
USER1.JS
import React from 'react';
import { BrowserRouter, Route, Switch, Link } from 'react-router-dom';
import User2 from './user2.js';
const User1 = (props) => {
return(
<BrowserRouter>
<div>
<Link to ="/user2">
<button onClick={props.change}>Next page</button>
</Link>
<Switch>
<Route path="/user2" exact component={User2}/>
</Switch>
</div>
</BrowserRouter>
); // end of return
};
export default User1;
USER2.JS
import React from 'react';
const User2 = (props) => {
console.log(props)
return(
<div>
{props.testValue ?
<p>test works</p>
:
<p>test does not work</p>
}
</div>
);
};
export default User2;
This is what i expected - test works
This is what i got - test does not work
You want to pass a custom property through to a component rendered via a route. Recommended way to do that is to use the render method.
<Route path="/user2" exact render={(props) => <User2 {...props} testValue={true} />} />
I think a valid inquiry here would be what are you wanting to pass through as an extra prop? whats the use case here? You may be trying to pass data in a way you shouldn't (context would be nice :D).

Props don't seem to be passed along in a React app

I recently started working with React so forgive me if my question is very basic. Props in a component don't seem to be passed along.
Below is my code.
dogDetails component
import React from 'react';
const DogDetails = (props) => {
return (
<div>
<h4>{'Dog details of '+ props.breed}</h4>
</div>
)
};
export default DogDetails;
In Dog component I have a method that returns a DogDetails component as shown below.
import React , {Component} from 'react'
import Dog from './Dog/Dog';
import classes from './Dogs.css';
import Aux from '../../hoc/Auxillary/Auxillary';
import {Route} from 'react-router-dom';
import DogDetails from './Dog/DogDetails/DogDetails';
class Dogs extends Component {
state = {
loadedDogs: []
};
componentDidMount () {
this.setState({
loadedDogs:[]
})
}
dogDetailsHandler = (dog) =>{
console.log(dog.breed);
return <DogDetails breed={dog.breed}/>;
};
render() {
const loadDogs = this.state.loadedDogs.map(dog => {
return <Dog
url={dog.images[0].image1}
alt={dog.id}
breed={dog.breed}
temperament={dog.temperament}
id={dog.id}
key={dog.id}
clicked ={() => this.dogDetailsHandler(dog)}>
</Dog>
});
return (
<Aux>
{loadDogs}
</Aux>
)
}
}
export default Dogs;
I have omitted the content of the loadedDogs array to reduce the code size.
Below is the Dog component
import React from 'react';
import classes from './Dog.css';
import {Link, Route} from 'react-router-dom';
const dog = (props) => {
return(
<div className={classes.Dog}>
<div>
<img src={props.url} alt ={props.id}/>
</div>
<div>
<h4>{'Breed: ' + props.breed}</h4>
<h5>{'Temperament: ' + props.temperament}</h5>
<p>
<Link to = '#'>... Read more ...</Link>
</p>
<Link to={'/shop/'+ props.id}>
<button onClick={props.clicked}>Order</button>
</Link>
</div>
</div>
)
};
export default dog;
I'm routing the DogDetails in the MainContent component like this.
import React from 'react';
import classes from './MainContent.css';
import Dogs from './Dogs/Dogs';
import Contact from '../Contact/Contact';
import {Route} from 'react-router-dom';
import DogDetails from './Dogs/Dog/DogDetails/DogDetails';
const main = () =>{
return (
<div className={classes.MainContent}>
<Route path='/' exact component = {Dogs}/>
<Route path='/shop' exact component = {Dogs}/>
<Route path={'/shop/:id'} exact component={DogDetails}/>
<Route path='/contact' exact component ={Contact}/>
</div>
)
};
export default main;
Here is a sample code sandbox to demonstrate what I'm trying to work on. I want the DogDetails component to show up when the Order button is clicked.
Code Sandbox
The dogDetails component <h4> tag is returning undefined. Please help me find where I'm doing it wrong.
Capitalize both dogDetails and dogDetailsHandler
User-Defined Components Must Be Capitalized
from react docs
Codesandbox example
Since you are using routing, I'm not sure why you have a button handler inside of a routed <Link />. Clicking on this element will route you to /shop/:id, and the return method of dogDetailsHandler will do nothing.
I have emulated your code and added a <Route /> I'm not sure if this is what you are after, but when I click "Order", I'll get routed to /shop/:id with the DogDetails component being rendered as it should.
Add this routing component after your <Link /> component and see if this is the behavior you are after.
<Route path="/shop/:id" render={
() => <DogDetails {...props} />
} />

Resources