Using react-router v0.12.4.
Are Route names supposed to be unique? The following doesn't seem to work.
<Route name='app' path='/' handler={MainApp} >
// instead of DefaultRoute, we use path matching
<Route path="/" name="dashboard" handler={Dashboard}>
<DefaultRoute name="main" handler={DashboardMain}/>
<Route name='settings' handler={DashboardSettings} />
</Route>
<Route name='settings' handler={AppSettings} />
</Route>
As per https://github.com/rackt/react-router/issues/890#issuecomment-76475626, a maintainer has clarified that Route names are unique:
Yes, they are supposed to be unique. We used to warn you about it.. we
should probably still do that.
Related
I am new to React learning , and was trying to build an app using react-router-dom. I was able to implement basic routing when I came across the term 'switch'. Can anyone please explain me with a use-case example where we use switch and what is its use?
Since you are new am going to take a bit more time to explain with examples and also add some few things about it you may want to have handy.
So like Iddler said, Switch is more or less like the "Switch case" condition in any other languages but usually ends with the first match it finds.
<Switch>
<Route path="/home" component={Home} />
<Route path="/about" component="{About} />
</Switch>
That is an example of its most basic use. Switch determines the start and end of the block or condition. Each Route checks for the current path. supposing we were working on "www.test.com". All of "www.test.com" is the root "/". So the Route checks for the path after the root. so if you had "www.test.com/home", "/home" comes after the root so the "Home" component will be loaded in our example above and if you had "www.test.com/about" the "About" component is loaded.
Be mindful that you can use any names. the components and paths do not need to be the same.
There are also cases when you might want to use exact to match an exact path. this is useful when you have similar paths. eg "/shop" and "/shop/shoes". using exact ensures Switch matches exact paths and not just the first.
Eg:
<Switch>
<Route exact path="/shop" component={Shop} />
<Route exact path="shop/shoes" component="{Shoes} />
</Switch>
You can also use <Route... /> without the <Switch>.
Eg:
<Route path="/home" component={Home} />
so unlike direct component loads where you just load a component like <Home /> Routers work with the URLs.
Lastly, the <Route... /> path can take arrays of url to load same component.
Eg:
<Switch>
<Route path={[ "/home", "/dashboard", "/house", /start" ]} component={Home} />
<Route exact path={[ "/about", "/about/management", "/about/branches" ]} component="{About} />
</Switch>
I hope this helps. Let me know if you need clarifications of any sort. :)
UPDATE:
You are not required to write Routers in this same format always. below is another format you could use;
<Router>
<Switch>
<Route path="/home">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
</Switch>
</Router>
There are instances like am in now where you want to be able to handle what shows when a wrong URL is entered. like a 404page. you could use Router without a path. so like a regular switch statement, that becomes your default.
<Switch>
<Route path="/home" component={Home} />
<Route path="/about" component="{About} />
<Route component="{PageNotFound} />
</Switch>
Switch looks through Route's children and renders the first one that matches the current path, once it does it will not look for any other matches.
The Switch component will work much in the same way as the Router component, meaning we will still have nested Route components that need exact paths, etc.
The added functionality of Switch is that it will only render the first matched child. This is really handy when we have nested routes such as the below:
<Switch>
<Route path="/accounts/new" component={AddForm} />
<Route path={`/accounts/:accountId`} component={Profile} />
</Switch>
Say we put the above code in a component — we would see that both {AddForm} and {Profile} would render, since “/accounts/new” could look like either Route to a Router component. Router components render inclusively of all route matches. The Switch component will render exact matches, and only the exact match. This makes it ideal for these nested scenarios.
I am building a web app with different routes.
There is this case where if a user hits any arbitrary route then he gets directed to Login Component. But it only handles case where bad routing happens this way localhost:3000/gvgdvgdvgd.
I have routes such as /home/news. A user may end up hitting /home/news/10 manually which doesn't exist. Similarly there is a route such as coupon and user may end up hitting /coupons/88 without going to coupons first.
How do I handle these issues in my web-app? I handled it for the first case. Here is the routing config.
<Route path="/login" component={LoginLoadable} />
<Route path="/home" component={Home} />
<Route path="/maths" component={Maths} />
<Route
exact
path="/"
render={routeProps => (
<Component1
{...routeProps}
/>
)}
/>
<Route component={LoginLoadable}/>
What about the case where user hits maths/123/1ydhd manually when that doesn't exist?
Wrap your routes in a Switch and add a Route with no path prop that renders your 404 page. If you don't specify a path, it should always render that route. Adding a Switch makes sure only one route will render. Also you will need to add the exact prop to your routes. See:
https://reacttraining.com/react-router/web/api/Route/exact-bool for how it matches sub-routes.
Something like:
<Switch>
<Route path="/login" component={LoginLoadable} />
<Route exact path="/home" component={Home} />
<Route exact path="/maths" component={Maths} />
<Route
exact
path="/"
render={routeProps => (
<Component1
{...routeProps}
/>
)}
/>
<Route component={LoginLoadable}/> // <-- remove this since you render it in '/login'
<Route component={A404Page} // <-- add this
</Switch>
I can't visit dashboard/job/123/status, I guess it has clashes?
<Route
exact
path="/dashboard/job/:jobId/:notificationId?"
component={Jobs}
/>
<Route exact path="/dashboard/job/:jobId/status" component={JobStatusContainer} />
As Kyle mentioned, you need to reverse the order of your routes.
<Route exact path="/dashboard/job/:jobId/status" component={JobStatusContainer} />
<Route
exact
path="/dashboard/job/:jobId/:notificationId?"
component={Jobs}
/>
The order you have it, dashboard/job/123/status is being consumed by /dashboard/job/:jobId/:notificationId? path and never reaching the check for the /dashboard/job/:jobId/status path, because it thinks you want status to be the value of :notificationId
My routing looks like this
<Route path="account" component={Page1}>
<Route path="new" component={Page2}/>
<Route path="(:userId)" component={Page1}/>
</Route>
Whenever I go to account/new it defaults to the (:userId) path and directs me to Page1 treating 'new' as the optional parameter. How can I make it default to Page2?
I am using V3 of react-router
It is going to Page1 because account needs to be an exact path. Since it isn't, when you go to account/new it will show the component for account. Try this:
<Route exact path="/account" component={Page1}>
<Route path="/new" component={Page2}/>
<Route path="/(:userId)" component={Page1}/>
</Route>
I have this structure
<Route path="user" component={Users}>
<Route path=":userId" component={User}>
<Route path=":project" component={Project}/>
<Route path="*" component={NotFound} />
</Route>
<Route path="*" component={NotFound} />
</Route>
<Route path="*" component={NotFound} />
No matter how hard i try to set <NoMatch />, I always can get through url to either user id or project id that doesnt exist. This is boggling me for two days now and I'm so confused by different approaches / answers over the internet that I'm lost.
Using react-router v3.0.2
Edit: I was completely on the wrong track before. What I meant was, the fallback is for routes that are not defined, so something like /foo.
/user/55 and user/55/project are valid routes even if you don't have user no. 55 in your database - you can't use the fallback here.