<Route exact path='/admin/task/create' component={ComponentA} />
<Route exact path='/admin/task/:id' component={ComponentB} />
I visit http://localhost:3000/task/123 it will trigger ComponentB, but when I hit http://localhost:3000/task/create it will hit ComponentB and ComponentA, why is it so? I thought exact prop alrdy solve that?
I think your routers independent of each other, so the second router receives "create" as :id.
You have to wrap your routers with the Switch
<Switch>
<Route exact path='/admin/task/create' component={ComponentA} />
<Route exact path='/admin/task/:id' component={ComponentB} />
</Switch>
https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Switch.md
Related
I'm in the process of trying to figure out how React Router Dom works, and have run into a problem that I am not even sure how to figure out.
If, within App.js, I have this snippet, then everything renders and navigates between the sections, just fine.
<Switch>
<Route path='/login-user' component={UserLoginForm} />
<Route path='/login-database' component={LoginDatabaseSelect} />
<Route path='/login-project' component={LoginProjectSelect} />
<Redirect path='/' exact to='/login-user' />
</Switch>
However, that is not the proper way, and I am trying to instead do this:
Create a different component that is referenced for this.
<Switch>
<Route path='/login' component={LoginSequence} />
<Redirect path='/' exact to='/login' />
</Switch>
And in LoginSequence the code is:
import React from 'react';
import { Route, Redirect, Switch } from 'react-router-dom';
import UserLoginForm from "./LoginSequence/loginUserPass";
import LoginDatabaseSelect from "./LoginSequence/loginDatabaseSelect";
import LoginProjectSelect from "./LoginSequence/loginProjectSelect";
class LoginSequence extends React.Component {
render () {
console.log('Login Sequence')
return (
<div>
<h1>Login Sequence</h1>
<Route path='/login-user' component={UserLoginForm} />
<Route path='/login-database' component={LoginDatabaseSelect} />
<Route path='/login-project' component={LoginProjectSelect} />
<Redirect path='/login' exact to='/login-database' />
</div>
)
}
}
export default LoginSequence;
however, this component, does not even seem to be called as the console.log does not output anything to console. Meaning that nothing is rendering, and it is not getting called.
Can someone point me in the right direction as to why this isn't working?
Edit: I fixed up the From and changed it to Path in the snippet of code where LoginSequence is called, since it had no effect, but path seems to be the normal way of doing it.
Change from to path in Redirect.
<Switch>
<Route path='/login' component={LoginSequence} />
<Redirect path='/' exact to='/login' />
</Switch>
Don't use Redirect use Route and call in the component you want to render
<Switch>
<Route path='/login-user' component={UserLoginForm} />
<Route path='/login-database' component={LoginDatabaseSelect} />
<Route path='/login-project' component={LoginProjectSelect} />
<Route path='/' exact component={login-user} />
</Switch>
After talking to a couple of people, and seeing a few more examples, something became a bit more clear that solved the issue.
Within App.js:
<Switch>
<Route path='/login' component={LoginSequence} />
<Redirect path='/' exact to='/login' />
</Switch>
And the LoginSequence component within LoginScreen.js:
class LoginSequence extends React.Component {
render () {
console.log('Login Sequence')
return (
<div>
<h1>Login Sequence</h1>
<Route path='/login/user' component={UserLoginForm} />
<Route path='/login/database' component={LoginDatabaseSelect} />
<Route path='/login/project' component={LoginProjectSelect} />
<Redirect path='/login' exact to='/login/user' />
</div>
)
}
}
What I noticed, is that the 'root' for referencing changes every time, so, once I redirect to /login to be loginsequence, the new area that components are looked for is within /login. Thus /login/<user/database/project> has to be the new path, rather than just /<user/database/project>, as it seems to look for the references of that, within App.js and can't find them, thus not rendering. Seems like RRD follows a 'tree' structure of a sort, and every time you want to nest it, you have to follow the structure of
/<path of component containing further routes>/<route of component referenced in component>
I'm having a Parent Container like this:
<Router>
<Switch>
<Route path="/website" component={Website} />
<Route path="/dashboard" component={Dashboard} />
</Switch>
</Router>
And both the Website and Dashboard components has another set of routes.
<Router>
<Switch>
<Route path="/page-one" component={PageOne} />
<Route path="/page-two" component={PageTwo} />
</Switch>
</Router>
//dash
<Router>
<Switch>
<Route path="/dash-page-one" component={DashOne} />
<Route path="/dash-page-two" component={DashTwo} />
</Switch>
</Router>
And Inside PageOne again, I have a child component, from where I want to navigate to <Dashboard /> (another parent) component but it didn't leave the current page, but the route changed.
function(){
<Link to="/dashboard">
Go to dashboard.
</Link>
}
You should only render the router component once by wrapping it around the root of your app, than you should be able to split the the routes navigating to anything inside the router. By creating separate router instances you are in essence creating separate routing environments.
I'm trying to implement the React HashRouter from react-router-v4... It works perfectly when I navigate over the page when using all the buttons...
But on a Page refresh I get a strange behavior. May someone of you can help me. Here's my code:
<HashRouter basename='/app'>
<Route component={App} />
</HashRouter>
And then, my Router:
<Switch>
<Route path='/statistics' component={Statistics}/>
<Route path='/search' component={Search}/>
<Route path='/settings' component={User}/>
<Route path='/demo' component={Demo}/>
<Route path='/' component={Statistics}/>
<Route render={() => <SiteNotFound />} />
</Switch>
Whenever I reload the page, the "Statistics" component get rendered, because the http://localhost:8080/#/app/demo I expect the Demo component to be rendered, but I get the Statistics Component.
Can someone explain me this behavior?
Thanks
Use this <Route path='/' exact component={Statistics}/>
When I try to have nested routes on my root route I run into a problem.
I have 3 "main" routes:
<Switch>
<Route path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/logout" component={Logout} />
</Switch>
On my Home component I have a nested router like this:
<div>
<Route path="/" render={() => <div>Home</div>} />
<Route path="/test" render={() => <div>Test Route</div>} />
</div>
The Home component has a sidebar HOC which contains the Links.
<Sidebar>
<Link to="/">Home</Link>
<Link to="/test">Test</Link>
<Link to="/logout">Logout</Link>
</Sidebar>
When Im on my Root component and click the Test link, the route on the nested router changes to the Test component which is correct. Whenever I go the login and/or logout route it tries to display that in the nested router in the Home component
Any idea what is going wrong?
EDIT: I've tried the example #Tholle provided. Unfortunately it still doesn't work the way I want to. See this CodeSandBox I made to reproduce my problem.
your links need to point to "/home/testX" and the nested routes need to handle "/home/testX". Also you will need a route for "/home" in the root. I don't believe the Link component is scoped to the route in which it is called. Meaning that to link to "/test1" assumes that is the base route. However, the rendering of test1 actually takes place in the home component.
To put it another way: In order to get to /home/test1 you must first get the home component (/home) to render which can then render the route for test1 (/home/test1)
Here's the codesandbox
Here is an example that provides a bit more flexibility codesandbox. This one will require a redirect of "/" because it depends on the path being used and it needs to be "/home" not "/".
Hope this helps. Hope I got it all right.
The Switch component makes sure that only the first Route that matches is rendered. To stop <Route path="/" component={Home} /> from always being rendered, you can set the exact prop to true.
Example (CodeSandbox)
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/logout" component={Logout} />
</Switch>
I have 2 level of route, the first layer it look like this
<BrowserRouter>
<div>
<AuthRoute></AuthRoute>
<Switch>
<Route path='/dashboard' component={Dashboard} />
</Switch>
</div>
</BrowserRouter>
where in AuthRoute I have a redirect upon componentDidMount
this.props.history.replace(/dashboard/redirected)
The problem is within the dashboard/index which is my 2nd level of route config
<BrowserRouter>
<Switch>
<Route exact path='/dashboard' component={()=><h1>dashboard index</h1>} />
<Route exact path='/dashboard/somewhere' component={()=><h1>somewhere</h1>} />
<Route exact path='/dashboard/redirected' component={() => <h1>redirected</h1>} />
</Switch>
</BrowserRouter>
The route changed to /dashboard/redirect but the component didn't render the correct one if you refresh on says /dashboard/somewhere or /dashboard/
You can see the problem clearer in the demo I setup https://codesandbox.io/s/v0v4qok38l
You only need one <BrowserRouter> in the application - removing it from dashboard/index.js will fix your issue.