The code below will render a link that I can click on, and when I click on it, I can see the URL changing to have /japanese_game for the URL path. However... nothing appears to change on the page, the link that says "Japanese" is still there, unchanged. It should display the other stuff in <Route path="/japanese_game">, or rather, that's what I would like it to do.
What am I doing wrong?
import React from 'react';
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
import './App.css';
function App() {
return (
<div className="App container">
<Router>
<Switch>
<Route path="/">
<Link to="/japanese_game">
<div className="language-option">
Japanese
日本語
</div>
</Link>
</Route>
<Route path="/japanese_game">
<h1>Japanese Game</h1>
<Link to="/">
Go back
</Link>
</Route>
</Switch>
</Router>
</div>
);
}
export default App;
Change the order, it compares and selects on the basis of which matches first. put the Route with "/japanese_game" first.
The <Switch> component render the first route he match (doc).
When you go to /japanese_game, you also hit / route, so he render the component under the / route.
To prevent that, you have 2 options:
Add an exact props to your route / : <Route exact path="/"> (hightly recommanded)
Change the ordre of your route (not recommanded at all)
Change the order of the routes or alternatively use an "exact" flag.
<Route exact path="/japanese_game">
Related
i am new to react and facing a problem. I have a page which contain two tabs. I want to make a hash URL so that it can redirect to corresponding tabs on the basis of url hash. Similarly when i open the page and change a tab, url also updates. Kindly answer in a detailed way as i am new to this and donot know about professional terms.
Moreover i am also bound to use react router for this.
Note: I am using typescript in case it changes something for my solution.
Thanks in advance.
HashRouter uses a hash symbol in the URL, which has the effect of all subsequent URL path content being ignored in the server request (ie you send "www.mywebsite.com/#/person/id" the server gets "www.mywebsite.com". As a result, the server will return the pre # URL response, and then the post # path will be handled by parsed by your client-side react application.
example code :
import React, { Component } from 'react';
import { HashRouter as Router, Route, Link, Switch }
from 'react-router-dom';
import Home from './component/home';
import About from './component/about';
import Contact from './component/contact';
import './App.css';
class App extends Component {
render() {
return (
<Router>
<div className="App">
<ul className="App-header">
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About Us</Link>
</li>
<li>
<Link to="/contact">
Contact Us
</Link>
</li>
</ul>
<Switch>
<Route exact path='/'
component={Home}>
</Route>
<Route exact path='/about'
component={About}>
</Route>
<Route exact path='/contact'
component={Contact}>
</Route>
</Switch>
</div>
</Router>
);
}
}
export default App;
So basically, I have a problem with react router not rendering my SystemSidebar. I want to scroll through my SystemSidebar components, but my problem is when I press on 'LinkSoundIcon' it redirects me to 'a new page' but that page doesnt render my systemSidebar . I want when I press on any of the links of my sidebar that my sidebar remains
import React from 'react'
import './SystemSidebar.css'
import SoundIcon from '#material-ui/icons/Computer';
import ComputerIcon from '#material-ui/icons/Computer';
import { BrowserRouter, Route, Switch, Link } from 'react-router-dom';
import Sound from './Sound';
import Computer from './Computer;
const SystemSidebar=()=> {
return (
<div className='system'>
<div className="sidebar">
<Link to='Sound'><VolumeUpIcon /></Link>
<h4> Sound</h4>
<Link to='Computer'><ComputerIcon /></Link>
<h4> Computer</h4>
</div>
</div>
);
};
import React,{Component} from 'react'
import Sound from './Sound';
import Computer from './Computer';
import SystemSidebar from './SystemSidebar';
class MainSystem extends Component {
render(){
return (
<div className="MAIN">
<BrowserRouter>
<SystemSidebar />
<Switch>
<Route exact path="/" component={SystemSidebar} />
<Route exact path="/Sound" component={Sound}/>
<Route exact path="/Computer" component={Computer}/>
</Switch>
</BrowserRouter>
</div>
);
}
}
export default MainSystem;
<Link to='/Sound'><VolumeUpIcon /></Link>
answer of your first problem and second if you want to access sidebar in each component then don't put it in switch route , simply put it outside the routing... or if u want to access it with specific route then try using nested routing
Okay, so it seems a little wonky with your copy pasting (I hope this is just a problem that stems from copy and pasting and it's not like that in your code). But your Problem is here:
<Route exact path="/Sound" component={Sound}/>
You're saying here that the route should be EXACTLY http://<your root uri>/Sound
You should also use this exact route in the link if you want to hit it, this means you need to have the slash there:
<Link to='/Sound'><VolumeUpIcon /></Link>
Update:
So according to your comment you want the sidebar to stay when you click a link. In this case, take a look at your code:
<Switch>
<Route exact path="/" component={SystemSidebar} />
<Route exact path="/Sound" component={Sound}/>
<Route exact path="/Computer" component={Computer}/>
</Switch>
You define here that the component SystemSidebar will only be loaded when you're at the Root directory ("/") of your App. It will be unloaded when you change that directory, for example, to "/Sound". SystemSidebar will be unloaded and Sound will be loaded instead.
Since your Sidebar should always be shown, it needs to be in your Main App and outside of your actual Router logic. Remember what the React Router does: It switches out components depending on which directory (which Sub-URL) you're in. It's best practice to have a Sidebar, an App Bar or similar things that are always there to be their own components. Your actual content should live in a separate container, where the needed component can be swapped out by the Router if need be. So something like this:
class MainSystem extends Component {
render(){
return (
<div className="MAIN">
<SystemSidebar />
<div className="ContentContainer">
<BrowserRouter>
<Switch>
<Route exact path="/Sound" component={Sound}/>
<Route exact path="/Computer" component={Computer}/>
{/* Route "/" should be last because it acts as fallback! */}
<Route exact path="/" component={StartPage} />
</Switch>
</BrowserRouter>
</div>
</div>
);
}
}
That's pretty basic but I hope you get the gist of it.
Also, I'd encourage you to take a look at an UI framework like Material UI for example. It already provides components ready for use (like your Sidebar which is called Drawer there), it's mobile first and easy to use with responsive design.
I'm building a new chrome extension using ReactJS, and I'm trying to redirect on '/' (default) to an existing route using the component of react-router.
For some reason, I can see it when I compile it to localhost, but when I upload it as a chrome extension I can't see it anymore.
What I thought about is that maybe there is another route that is in use as the main route in chrome extension instead of '/'.
I tried to console.log it but for some reason, it is not showing me the logs.
Thanks!
<div className="App">
<BrowserRouter>
<Navbar />
<Route
path="/"
exact
render={() => <Redirect to="/navigatehere" /> }
/>
<Route
path="/navigatehere"
exact
render={() => <NavigateHere />}
/>
</BrowserRouter>
</div>
);
}
export default App;
First Of all you need Switch to use exact prop.
You can import it like this.
import {BrowserRouter, Switch, Route}
// Then you have to use
<BrowserRouter>
<div>
<Switch>
<Route path='/' exact /*render Whatever you want after this . . .*/ />
</Switch>
</div>
</BrowserRouter>
Second of all, I use component prop instead of render().
Like this -
import DummyComponent from './DummyFolder/DummyComponent;
import React from 'react'
import {BrowserRouter as Router, Switch, Route}
<BrowserRouter>
<div>
<Switch>
<Route path='/' exact component={DummyComponent}/> // This will render the component in the respective path
</Switch>
</div>
</BrowserRouter>
However render() should also work for you if you use <Switch>. It is working without Switch for rest of the router because you are not specfing path as '/' for all the <Route />. If you want to route to '/', then Switch is compulsory. You can also refer DevEd 's YouTube channel for more understanding. He has made an exclusive video on React Router. Check that out Here ◀ ◀ ◀.
I have a table which is as shown below
I have a component which displays the details
How to display the details when click on the first tab of the table
i.e, when clicked on the number 1053 in the first column how to redirect to component with the parameter
Not sure how to build the route localhost:3000/#/sitepage/1053
Is there a way to directly get the route localhost:3000/#/sitepage/1053 so that i can give in the href of the table
Read about https://www.tutorialspoint.com/reactjs/reactjs_router.htm
but not sure how this link to route to write
Please point me to a document which will help me in doing
It you want to redirect to another component, you can use React Router Redirect
This section of React Router documentation will help you, since you haven't posted any code you tried I assumed you're looking for just some documentation to guide you.
Update:
Ok let's assume you have a Router like that:
<Router>
<Route exact path="/" render={(props) => <Table {...props} />}/>
<Route exact path="/column-details/:id" render={(props) => <ColumnDetails {...props} />}/>
</Router>
The props here has a history attribute, so in your <Table> you can have access to it by initializing your component like this
function Table({history}) {
// ...
}
Now in the first column, you need to add an onClick listener, let's say you use <TableCell> that would be
<TableCell onClick={() => history.push(`/column-details/${yourId}`)}/>
Now in your <ColumnDetails> component, we will need access to match attribute to extract our id from the url, so it would be something like:
function ColumnDetails({match}) {
const id = match.params.id;
// ...
}
I hope this is clear enough.
I think you can try react-router-dom to solve your problem, react-router-dom is a wrapper on top of react-router, which brings more flexibility
Let say your table is under Equipments component, then you have to add <Link/> component as alternate to <a> as follows, assuming your equipment object got url and title property
<Link to={`${equimpement.url}`}>{equimpement.title}</Link>
Please note that if you want to use Link component you have to import it on top
import { Link } from "react-router-dom";
And you can manage your routing in your App.js like this way
<div className="content">
<Switch>
<Route path="/not-found" component={NotFount} />
<Route path="/equipments/:id" exact component={EquipmentForm} />
<Route path="/equipments" component={Equipments} />
<Route path="/" exact component={Home} />
<Redirect to="/not-found" />
</Switch>
</div>
Make sure you have imported Route, Redirect and Switch as well in your on top of your App.js
import { Route, Redirect, Switch } from "react-router-dom";
Update
And last if you want to use Route in your app you must wrap your with BrwoserRouter
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root")
);
with its import import { BrowserRouter } from "react-router-dom";
I'm new to React and React Router. I'm using React Router v4 and following a tutorial based on previous versions - but I made it work (using some stuff found on SO and some stuff on the react router v4 docs).
There is one thing though that is bothering me.
I have a url http://localhost:3000/#/bugs, which basically loads a list of all my bugs. But I also have possible urls like http://localhost:3000/#/bugs?priority=low&status=open which loads a specific set of urls.
The urls themselves work and do the job as expected.
The werid thing is that whenever I type http://localhost:3000/#/bugs?priority=low&status=open (or any params), the component do their jobs but the URL address bar shows http://localhost:3000/#/bugs (although the rendering shows everything related to priority and status shown).
Somehow, the URL location bar is changed but I don't understand why.
Here is my App.js
import React from 'react';
import ReactDOM from 'react-dom';
import {BugList} from './BugList';
import {Redirect} from 'react-router';
import {HashRouter as Router, Route} from 'react-router-dom';
const NoMatch = React.createClass({
render : function (){
return(
<h2>This path does not exist</h2>
);
}
});
ReactDOM.render(
(
<Router>
<div>
<Route path='/bugs' component={BugList}/>
<Route path='/bugs/priority/:priority' component={BugList}/>
<Redirect from='/' to="/bugs" />
<Route path="*" component={NoMatch} />
</div>
</Router>
),
document.getElementById('main')
);
Thanks in advance.
EDIT 12th of April. Despite of the precious help of someone below, this is still not solved. I tried using Switch inside a Router but it doesn't work at all (nothing is shown). So the problem is still happening, and this is the current state of my App.js, using react-15.5.3, react-dom-15.5.3, react-router-4.0.0 and react-router-dom-4.0.0....
import React from 'react';
import ReactDOM from 'react-dom';
import {BugList} from './BugList';
import BugEdit from './BugEdit';
import {Redirect} from 'react-router';
import {HashRouter as Router, Route} from 'react-router-dom';
const NoMatch = React.createClass({
render : function (){
return(
<h2>This path does not exist</h2>
);
}
});
ReactDOM.render(
(
<Router>
<div>
<Redirect from='/' to="/bugs" />
<Route path='/bugs' component={BugList}/>
<Route path='/bug/:id' component={BugEdit}/>
<Route path="*" component={NoMatch} />
</div>
</Router>
),
document.getElementById('main')
);
The problem is that even if you enter the URL with query this URL matches Redirect path (since it's just / any URL matches this pattern) so the redirection to /bugs occurs. You have to use Switch (remember to import it) to render only the first <Route> or <Redirect> that matches the URL:
<Router>
<Switch>
<Route path='/bugs' component={BugList}/>
<Redirect from='/' to="/bugs" />
...
</Switch>
</Router>
The problem occured only on page load and not on re-entering the URL because your routing is based on hashes and the browser doesn't reload page when only hash part changes.
Please note that Redirect component in React-Router v4 performs redirection only when it's rendered - it doesn't set up permanent redirection rule so in your case redirection works only on page load. If you'd like your app to always redirect given URL you'd have to define Route for URL you'd like to redirect from and render Redirect:
<Route path='/oldUrl' render={() => (
<Redirect to="newUrl" />
)}/>
Furthermore, React-Router v4 is quite different from v3 so I don't recommend using v3 tutorials - it doesn't make sense.
Building on what Bartek said: if you use Switch, it will go directional from top to bottom and render the first hit, since you moved your redirect to the first position it will always hit that first and then not go to the other routes. Which is why your Switch should look like this imho (untested):
<Router>
<Switch>
<Route path='/bugs' component={BugList}/>
<Route path='/bug/:id' component={BugEdit}/>
<Redirect from='/' to="/bugs" />
<Route path="*" component={NoMatch} />
</Switch>
</Router>
I know its 04/2020, but this will fix your issue.
<Switch>
<Route path='/bug/:id' component={BugEdit}/>
<Route path='/bugs' component={BugList}/>
<Redirect from='/' to="/bugs" />
<Route path="*" component={NoMatch} />
</Switch>
</Router>```