I want to route specific component in other component but when I click on the link other components are disappeared
import React from 'react';
import { Route, Switch, BrowserRouter } from 'react-router-dom';
import Sidebar from '../componants/Sidebar'
import Navbar from '../componants/Navbar';
import Router from '../Routers/Routers'
import Answer from './Answer';
import Feed from './Feed'
const Layuot = () => {
return (
<>
<div className="container-fluid">
<Navbar />
<div className="rows row">
<div className='col-3'>
<Sidebar/>
</div>
<div className="col-9 ">
<div className="content">
<Switch>
<Route path='/feed'><Feed/></Route>
<Route path = '/answer/:q_id'><Answer/></Route>
</Switch>
</div>
</div>
</div>
</div>
</>
)
}
export default Layuot;
see output
enter image description here
See Url
enter image description here
Every component are disappeared and Feed component not ms
Related
I'm having a problem with react-route. The NoteList component is not rendering.
app.js
import { BrowserRouter as Router, Routes } from 'react-router-dom';
import logoNotes from './img/logoNotes.png';
import NoteList from './components/NoteList/NoteList';
import './App.css';
function App() {
return (
<Router>
<div className='aplication-notes'>
<div className='notes-logo-container'>
<img src={logoNotes} className='notes-logo' alt='logo' />
</div>
<div className='note-list'>
<h1> my notes</h1>
<br></br>
<Routes
path='/src/components/NoteList/NoteList'
element={<NoteList />}
/>
</div>
</div>
</Router>
);
}
export default App;
I can see the div and h1 that is in the app.js file but not the Notelist component.
How can I solve this problem?
The Routes component is only responsible for wrapping Route components and handles the path matching duties. It doesn't take path or element props. These belong to the Route component.
Import the Route component and render the NoteList component by the Route and wrap the Route with Routes.
Example:
import {
BrowserRouter as Router,
Routes
Route // <-- import
} from 'react-router-dom';
import logoNotes from './img/logoNotes.png';
import NoteList from './components/NoteList/NoteList';
import './App.css';
function App() {
return (
<Router>
<div className='aplication-notes'>
<div className='notes-logo-container'>
<img src={logoNotes} className='notes-logo' alt='logo' />
</div>
<div className='note-list'>
<h1> my notes</h1>
<br />
<Routes> // <-- wrap Route components
<Route // <-- Route renders content
path="/src/components/NoteList/NoteList"
element={<NoteList />}
/>
</Routes>
</div>
</div>
</Router>
);
}
export default App;
Now when you navigate to "/src/components/NoteList/NoteList" in the browser you should see the UI rendered as well as the NoteList component.
// Warning: Cannot read properties of undefined (reading 'params')
// im try to get movie_id from movielist.js to view single movie on movie.js onclicking view review
// basically my error is from inability to pass the props into movie.js
//in nav/index.js
import { BrowserRouter as Router, Routes, Route, useParams} from "react-router-dom";
import Navbar from './navbar';
import MovieList from "../components/movie-list"
import Movie from "../components/movie"
const Nav = () => {
return (
<Router>
<Navbar/>
<Routes>
<Route exact path={'/'} element={<MovieList/>}/>
<Route path='/movies/:id/' element={<Movie props={useParams()} />} />
</Routes>
</Router>
)}
//in movielist.js
import React, {useState, useEffect} from 'react'
import MovieDataService from "../services/movie"
import { Link } from 'react-router-dom'
const MovieList = () => {
....
return (
<div>
....
<div>
{movies.map((movie)=>{
return(
<div className="card" key={movie._id}>
<div className="card-container">
<div className='card-img'>
<img src={movie.poster+"/100px180"} alt=""/>
</div>
<div className="card-body">
<h1>{movie.title}</h1>
<h2>Rating:{movie.rated}</h2>
<p>{movie.plot}</p>
<Link to={"/movies/"+movie._id}>View Review</Link>
</div>
</div>
</div>
);
})}
</div>
</div>
)
}
// in movie.js
import React, { useState, useEffect } from 'react'
import MovieDataService from '../services/movie'
import { Link } from 'react-router-dom'
const Movie = (props) => {
useEffect(()=>{
getMovie(props.match.params.id)
},[props.match.params.id]) //won't call getMovie Multiple times unless id is updated.
return (
<div>
<div className="card-container">
<div className='card-img'>
<img src={movie.poster+"/100px250"} alt=""/>
</div>
<div className="card-body">
<h1>{movie.title}</h1>
<p>{movie.plot}</p>
{props.user && <Link to={"/movies/"+props.match.params.id+"/review"}>Add Review</Link>
}
</div>
</div>
);
})}
</div>
</div>
)
}
Use useParams() hook to get url params.
const {id} = useParams()
useEffect(()=>{
getMovie(id)
},[id])
replace props.match.params.id with id everywhere
am trying to build an E-Commerce website with ReactJS(Without any backend or server).
Totally I have 4 components:
Navbar.jsx
Home.jsx
Products.jsx
Cart.jsx
**what i want is, when user clicks on ADD TO CART button in products.jsx, cart number should be displayed on Navbar top right corner but its not displaying.
what i tryed: i just passed props from Products.jsx page to Navbar.jsx but its not working. i tried lot but am unable to do it.. please help me...Thanks in Advance
[am familiar with functional components only]**
CODE : Navbar.jsx
import React from 'react'
import { Link } from 'react-router-dom'
function Navbar(props) {
return (
<div>
<div className="d-flex bg-primary flex-row justify-content-between text-light ">
<div className="left d-flex">
<li className="my-2"><Link className="text-light p-3 py-2" to="/">HOME</Link></li>
<li className="my-2"><Link className="text-light p-3 py-2" to="/products">PRODUCTS</Link></li>
<li className="my-2"><Link className="text-light p-3 py-2" to="/cart">CART</Link></li>
</div>
<div className="right">
<p>CART is:</p><p className="mx-2 h3">{props.text}</p>
{/* I WANT TO DISPLAY THE CART ABOVE HERE */}
</div>
</div>
</div>
)
}
export default Navbar
CODE : Products.jsx
import React, { useState } from 'react'
import Router from '../Router';
import Navbar from './Navbar';
function Products() {
return (
<div>
<h1>PRODUCTS</h1>
<button className="btn btn-success">ADD TO CART</button>
{/* WHEN I CLICK ON ADD TO CART, CART NUMBER SHOULD UPDATED IN NAVBAR */}
</div>
)
}
export default Products
CODE : Router.jsx
import React from 'react'
import {
BrowserRouter,
Switch,
Route,
Link
} from "react-router-dom";
import Home from './components/Home';
import Navbar from './components/Navbar';
import Products from './components/Products';
import Cart from './components/Cart';
function router() {
return (
<>
<BrowserRouter>
{/* <Navbar text="3"/> */}
<Navbar/>
<Switch>
<Route exact path='/' component={Home}/>
<Route exact path='/cart' component={Cart}/>
<Route exact path="/products" component={Products}/>
</Switch>
</BrowserRouter>
</>
)
}
export default router
CODE : index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Home from './components/Home';
import Navbar from './components/Navbar';
import Products from './components/Products';
import './index.css';
import {
BrowserRouter,
Switch,
Route,
Link
} from "react-router-dom";
import Router from './Router';
ReactDOM.render(
<Router />
,
document.getElementById('root')
);
FOLDER STRUCTURE:
folder structure
PLEASE HELP ME...THANKS IN ADVANCE
In Router.jsx, you need to have a state to store cart number
pass this state value as a prop to Navbar.jsx, when this state update, Navbar prop would be update, too
pass setState callback as a prop to Products.jsx, when click "Add To Cart", call this callback, then state value will be updated
Router.jsx
import React, { useState } from "react";
import { BrowserRouter, Switch, Route, Link } from "react-router-dom";
import Home from "./components/Home";
import Navbar from "./components/Navbar";
import Products from "./components/Products";
import Cart from "./components/Cart";
function Router() {
// a state to store cart number
const [text, setText] = useState(3);
return (
<>
<BrowserRouter>
<!-- pass state value as a prop to Navbar -->
<Navbar text={text} />
{/* <Navbar /> */}
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/cart" component={Cart} />
<!-- pass setText callback as a prop to Products -->
<Route
exact
path="/products"
component={() => <Products setText={setText} />}
/>
</Switch>
</BrowserRouter>
</>
);
}
export default Router;
Products.jsx
import React, { useState } from "react";
import Router from "../Router";
import Navbar from "./Navbar";
function Products(props) {
const { setText } = props;
return (
<div>
<h1>PRODUCTS</h1>
<!-- when button click, call setText to update text state -->
<button
className="btn btn-success"
onClick={() => {
setText((prev) => prev + 1);
}}
>
ADD TO CART
</button>
{/* WHEN I CLICK ON ADD TO CART, CART NUMBER SHOULD UPDATED IN NAVBAR */}
</div>
);
}
export default Products;
What you must do is transfer the value to display in the cart from the Products page to the navbar, on button click.
Both Navbar and Products components have a shared parent; Router.jsx. This means your value has to go from Navbar.jsx, up to a state in Router.jsx via a "callback". The state will then be given as the prop to the Navbar.
Following that approach will allow you to dynamically update. To summize; All you need is 1 state in Router, and 1 callback as prob in Navbar, which updates the state in Router.
For some reason, my web app is not directing to the component whenever I go to the parameters. Specifically, it is not going to the Battle component.
Here is what the navigation looks:
import React from 'react';
import Header from './components/Header/Header';
import SelectPlayers from './pages/SelectPlayers/SelectPlayers';
import Popular from './pages/Popular/Popular'
import Battle from './pages/Battle/Battle'
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
function App() {
return (
<Router>
<div className={'flex flex-column'}>
<Header />
<Switch>
<Route exact path={'/'} component={Popular}/>
<Route exact path={'/battle/select-player'} component={SelectPlayers} />
<Route exact path={'/results?playerOne=:playerOne&playerTwo=:playerTwo'} component={Battle} />
</Switch>
</div>
</Router>
);
}
export default App;
In the SelectPlayers component, whenever the user presses a button it runs:
import React, {useState} from 'react';
function SelectPlayers(props) {
const [playerOne, setPlayerOne] = useState('');
const [playerTwo, setPlayerTwo] = useState('');
function setPlayerName(event, player){
if (player === 1){
setPlayerOne(event.target.value)
} else if (player === 2) {
setPlayerTwo(event.target.value)
}
}
function goToBattle(event){
event.preventDefault();
props.history.push(`/results?playerOne=${playerOne}&playerTwo=${playerTwo}`)
}
return (
<div className={'pa3 mh7-l mh7-m'}>
<div className="flex flex-column">
<div className={'mb1'}>
<h1 className={'mb0'}>Player One</h1>
<input onChange={(e) => setPlayerName(e, 1)} type="text" placeholder={'github username'} className={'input-reset pa1 w-100 h2 ba b--black br2'}/>
</div>
<div className="tc dark-red">
<h1>Versus</h1>
</div>
<div className={'mb3'}>
<h1 className={'mb0 mt0 tr'}>Player Two</h1>
<input onChange={(e) => setPlayerName(e, 2)} type="text" placeholder={'github username'} className={'input-reset pa1 w-100 h2 ba b--black br2'}/>
</div>
<div>
<button onClick={(e) => goToBattle(e)} className={'input-reset pa1 h2 fw1 bg-black white ba w-100 b--black br2'}>Battle</button>
</div>
</div>
</div>
);
}
export default SelectPlayers;
On the Battle component, I write some console.log stuff just to check if the Component loaded. However, whenever I go to that parameter, none of the code in my componentDidMount is running. I don't see any of the console.logs I wrote in componentDidMount in my developer console. Here is the component:
import React, {Component} from 'react';
class Battle extends Component {
constructor(props){
super(props)
}
componentDidMount() {
console.log('runngins');
console.log(this.props);
}
render() {
return (
<div className={'pa3 mh7-l mh7-m'}>
<div className="flex flex-column">
</div>
</div>
);
}
}
export default Battle;
You can see the code at this repo: https://github.com/tarekgabarin/github_compete
It would be greatly appreciated if anyone helped me.
As per your new comment that code is working without queryset, looks like there is some problem with your queryset parameters.
As suggested in comment box, don't define Router with queryset.
<Switch>
<Route exact path={'/'} component={Popular}/>
<Route exact path={'/battle/select-player'} component={SelectPlayers} />
<Route exact path={'/results'} component={Battle} />
</Switch>
In your SelectPlayers component, navigate to next page with queryset.
props.history.push("/results?playerOne=" +playerOne+ "&playerTwo=" +playerTwo)
On Battle component, use (query-string) to read the parameter. For example:
const values = queryString.parse(this.props.location.search);
const player_one = values.playerOne
const player_two = values.playerTwo
Please note that my above code is not tested.
Thanks
Before I begin I have been on the https://reacttraining.com/react-router/web/guides/quick-start to grasp the idea of how the react router works. I have created a simple 3 page site in react and I want to create a list which will allow me to show some nested components. Whilst the examples on reacttraining.com nicely work on in a singles js file. I have my site split over 3 js files:
APP.JS
import React, {Component} from 'react';
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom';
import {Home} from './Home';
import {User} from './User';
import {Artwork} from './artwork'
import {Header} from './header';
class App extends Component {
render(){
return (
<Router>
<div className="container">
<div className="row">
<div className="col-xs-10 col-xs-offset-1">
<Header />
</div>
</div>
<hr/>
<div className="row">
<div className="col-xs-10 col-xs-offset-1">
<Route path="/" exact component={Home}/>
<Route path="/home" exact component={Home}/>
<Route path="/user" component={User}/>
</div>
</div>
</div>
</Router>
);
}
}
export default App;
USER.JS Edited on 28/03/2017
import React, {Component} from 'react';
import {Artwork} from './artwork';
import {Route, Link} from 'react-router-dom';
export class User extends Component {
render() {
return (
<div className="row">
<div className="col-md-4">
<h3>The User Page</h3>
<p>User ID:</p>
<li><Link to="/user/artwork">Artwork</Link></li>
</div>
<div className="col-md-8">
<Route path="/user/artwork" component={Artwork}/>
</div>
</div>
);
}
}
export default User;
ARTWORK.JS
import React, {Component} from 'react';
export class Art extends Component {
render(){
return (
<div>
<h3>Art</h3>
</div>
);
}
}
export default Art;
The issue that I am having is that whilst i can navigate through to my top level menu items (Home and User) I can not access the artwork component on the the user page. when the artwork button is pressed my user component is removed.
If you're looking at the basic example on react-training, you'll notice that the "child" Route in the Topics component has ${match.url}/:topicId as the path:
<Route path={`${match.url}/:topicId`} component={Topic}/>
This is basically turning it into topics/:topicId which is needed because the top most component wouldn't know what to do with just :topicId.
Likewise, in your situation, your App.js doesn't know what to do with /artwork so it doesn't render anything. If you change your Route path and Link to in User.js to /user/artwork it should start working as desired.
To make your User component more composable/reusable, you'd want to do the same thing as react training and use the passed in match.url on the props.