Route is not matched - javascript

I can't figure out why this is not matching my route for the CompanyDetailContainer. The route for Interview container works fine
<IndexRoute component={HomePageContainer} />
<Route component={InterviewContainer} name="interview" path="interviews/companies/:companyId" />
<Route component={CompanyDetailContainer} name="companydetail" path="interviews/companies/:companyId/details" />
so http://localhost:8080/interviews/companies/10 hits the interview route fine but http://localhost:8080/interviews/companies/501/details does not hit the companydetail route
UPDATE:
I'm using:
"react-router": "^3.0.0",
"react-router-dom": "^4.2.2",
original code:
import { IndexRoute, Router, Route, browserHistory } from 'react-router';
<Router history={browserHistory} onUpdate={onUpdate}>
<Route path="/">
<IndexRoute component={HomePageContainer} />
<Switch>
<Route exact component={InterviewContainer} name="interview" path="interviews/companies/:companyId" />
<Route exact component={CompanyDetailContainer} name="companydetail" path="interviews/companies/:companyId/details" />
</Switch>
<Route component={About} name="about" path="about" />
<Route component={JobList} name="jobs" path="jobs" />
</Route>
<Route component={Container} path="/" />
<Route component={NotFound} path="*" />
</Router>
adding just exact to what I had didn't work:
import { IndexRoute, Router, Route, browserHistory } from 'react-router';
<Router history={browserHistory} onUpdate={onUpdate}>
<Route path="/" component={HomePageContainer}>
<Route component={InterviewContainer} exact name="interview" path="interviews/companies/:companyId" />
<Route component={CompanyDetailContainer} exact name="companydetail" path="interviews/companies/:companyId/details" />
<Route component={About} name="about" path="about" />
<Route component={JobList} name="jobs" path="jobs" />
<Route component={Container} path="/" />
<Route component={NotFound} path="*" />
</Route>
</Router>
Then I tried to add switch around it:
import { Router, Route, Switch, browserHistory } from 'react-router';
<Router history={browserHistory} onUpdate={onUpdate}>
<Switch>
<Route path="/" component={HomePageContainer}>
<Route component={InterviewContainer} exact name="interview" path="interviews/companies/:companyId" />
<Route component={CompanyDetailContainer} exact name="companydetail" path="interviews/companies/:companyId/details" />
<Route component={About} name="about" path="about" />
<Route component={JobList} name="jobs" path="jobs" />
<Route component={Container} path="/" />
<Route component={NotFound} path="*" />
</Route>
</Switch>
</Router>
And now I get this error: Cannot read property 'createRouteFromReactElement' of undefined. I noticed my import for Switch is not resolving but that's how you import Switch right?
Also not sure if all those routes should be sub routes of <Route path="/" component={HomePageContainer}>? Note that I removed the <IndexRoute /> per suggestions too.

React Router V4 is split out into two packages. One for Web (DOM) and one for Native.
Therefore, you don’t need the react-router dependency, just react-router-dom.
So import the components from react-router-dom instead:
import { BrowserRouter, Route, Switch } from 'react-router-dom'
You can then wrap your routes in a Switch so that only one route is matched.
If you put your details route above the other then it should match first:
<BrowserRouter>
<Switch>
<Route exact path="/" component={HomePageContainer} />
<Route path="/interviews/companies/:companyId/details" component={CompanyDetailContainer} />
<Route path="/interviews/companies/:companyId" component={InterviewContainer} />
<Route path="/about" component={About} />
<Route path="/jobs" component={JobList} />
<Route component={NotFound} />
</Switch>
</BrowserRouter>
Also note that with React Router V4, you don’t nest routes. Instead you can add additional routes within your components.

Reverse the two routes with a wrapping with Switch :
import {Switch} from 'react-router';
<IndexRoute component={HomePageContainer} />
<Switch>
<Route component={CompanyDetailContainer} name="companydetail" path="interviews/companies/:companyId/details" />
<Route component={InterviewContainer} name="interview" path="interviews/companies/:companyId" />
</Switch>

There are 2 possible solutions:
Use a Switch, which is used to exclusively render just one route.
Use the exact prop of the Route component, which renders the component only if the path is an exact match.
Eg:
<Switch>
<Route exact component={InterviewContainer} name="interview" path="interviews/companies/:companyId" />
<Route exact component={CompanyDetailContainer} name="companydetail" path="interviews/companies/:companyId/details" />
</Switch>
P.S. I think you wouldn't need IndexedRoute when using Switch ( but you better check it in the docs of the version you are using)

Related

React how can i redirect the homepage?

My problem is ı have a routes like that but when i try for example http://localhost:3000/examp1
I just want to redirect to HomePage how can i do that when i write something http://localhost:3000/*** ı go the page but nothing shows how can i detect and how can i redirect the homepage ? anyone help ?
<Router>
<Switch>
<Route path='/' component={Home} exact />
<Route path='/xyz' component={asf} exact />
<Route path='/asd' component={asd} exact />
<Route path='/fasd/:slug' component={asd} exact />
<Route path='/asd' component={asd} exact />
<Route path='/asd/:slug' component={asd} exact />
<Route path='/asd' component={asd} exact />
<Route path='/asd' component={fas} exact />
<Route path='/asd' component={fasd} exact />
</Switch>
</Router>
Adding a <Route /> at the bottom without a path attribute inside the <Switch> tag should work for when there's no match, and then use a <Redirect /> tag to redirect to the homepage.
<Router>
<Switch>
<Route path='/' component={Home} exact />
<Route path='/xyz' component={asf} exact />
<Route path='/asd' component={asd} exact />
<Route path='/fasd/:slug' component={asd} exact />
<Route path='/asd' component={asd} exact />
<Route path='/asd/:slug' component={asd} exact />
<Route path='/asd' component={asd} exact />
<Route path='/asd' component={fas} exact />
<Route path='/asd' component={fasd} exact />
<Route component={() => <Redirect to="/" />} />
</Switch>
</Router>
How to properly render a 404 page in React with React-Router?
https://reactrouter.com/web/api/Redirect
You can simply use Redirect component of react-router-dom library.
<Router>
<Switch>
<Route path='/' component={Home} exact />
<Route path='/xyz' component={asf} exact />
<Route path='/asd' component={asd} exact />
<Route path='/fasd/:slug' component={asd} />
<Route path='/asd' component={asd} exact />
<Route path='/asd/:slug' component={asd} />
<Redirect to="/" />
</Switch>
</Router>
DefaultRoute and NotFoundRoute were removed in react-router 1.0.0.
I'd like to emphasize that the default route with the asterisk has to be last in the current hierarchy level to work. Otherwise it will override all other routes that appear after it in the tree because it's first and matches every path.
For react-router 1, 2 and 3
If you want to display a 404 and keep the path (Same functionality as NotFoundRoute)
<Route path='*' exact={true} component={My404Component} />
If you want to display a 404 page but change the url (Same functionality as DefaultRoute)
<Route path='/404' component={My404Component} />
<Redirect from='*' to='/404' />
Example with multiple levels:
<Route path='/' component={Layout} />
<IndexRoute component={MyComponent} />
<Route path='/users' component={MyComponent}>
<Route path='user/:id' component={MyComponent} />
<Route path='*' component={UsersNotFound} />
</Route>
<Route path='/settings' component={MyComponent} />
<Route path='*' exact={true} component={GenericNotFound} />
</Route>
For react-router 4 and 5
Keep the path
<Switch>
<Route exact path="/users" component={MyComponent} />
<Route component={GenericNotFound} />
</Switch>
Redirect to another route (change url)
<Switch>
<Route path="/users" component={MyComponent} />
<Route path="/404" component={GenericNotFound} />
<Redirect to="/404" />
</Switch>
The order matters!
I ma using Navigate to redirect from "/" to "/home"
import {BrowserRouter, Navigate, Route, Routes,} from "react-router-dom";
<BrowserRouter>
<Routes>
<Route exact path="/" element={<Navigate to="/home"/>} />
</Routes>
</BrowserRouter>

How to put a div inside a Switch with React Router?

I have an APP using React and Redux, and I wanted to load a NotFound component when the user enters an invalid route. I found online a way to solve that problem, that is by putting all the routes inside a switch, including the NotFound component.
The problem is that, in my app, I can't put all my routes inside a Switch because There is a single component that needs to be stretched to the entire page, while all the other components need to be inside a "container". The way I have it below (see the code), the NotFound component works for all cases, except when I'm on the "landing" component route (where the NotFound component always displays).
I tried to put the landing component inside the Switch with the "container" div but the app crashes.
Is there any way to solve this? (keeping the landing component out of the container, and the other components inside)
class App extends Component {
render() {
return (
<Provider store={store}>
<Router>
<div className="App">
<Navbar />
<Route exact path="/" component={Landing} />
<div className="container">
<Switch>
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={Login} />
<Route exact path="/profiles" component={Profiles} />
<Route exact path="/profile/:handle" component={Profile} />
<PrivateRoute exact path="/dashboard" component={Dashboard} />
<PrivateRoute
exact
path="/create-profile"
component={CreateProfile}
/>
<PrivateRoute
exact
path="/edit-profile"
component={EditProfile}
/>
<PrivateRoute
exact
path="/add-experience"
component={AddExperience}
/>
<PrivateRoute
exact
path="/add-education"
component={AddEducation}
/>
<PrivateRoute
exact
path="/edit-education/:id"
component={EditEducation}
/>
<PrivateRoute exact path="/feed" component={Posts} />
<PrivateRoute exact path="/post/:id" component={Post} />
<Route component={NotFound}/>
</Switch>
</div>
<Footer />
</div>
</Router>
</Provider>
);
}
}
You can make a separate router for all other components except landing page.
// App.js
import NonLandingPages from './NonLandingPages';
class App extends Component {
render() {
return (
<Provider store={store}>
<Router>
<div className="App">
<Navbar />
<Switch>
<Route exact path="/" component={Landing} />
<Route component={NonLandingPages}/>
</Switch>
<Footer />
</div>
</Router>
</Provider>
);
}
}
Separate router for all other pages
// NonLandingPages.js
class NonLandingPages extends Component {
render() {
return (
<div className="container">
<Switch>
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={Login} />
<Route exact path="/profiles" component={Profiles} />
<Route exact path="/profile/:handle" component={Profile} />
<PrivateRoute exact path="/dashboard" component={Dashboard} />
<PrivateRoute
exact
path="/create-profile"
component={CreateProfile}
/>
<PrivateRoute
exact
path="/edit-profile"
component={EditProfile}
/>
<PrivateRoute
exact
path="/add-experience"
component={AddExperience}
/>
<PrivateRoute
exact
path="/add-education"
component={AddEducation}
/>
<PrivateRoute
exact
path="/edit-education/:id"
component={EditEducation}
/>
<PrivateRoute exact path="/feed" component={Posts} />
<PrivateRoute exact path="/post/:id" component={Post} />
<Route component={NotFound}/>
</Switch>
</div>
);
}
}

React Router nested routes

I have routes:
<Switch>
<Route path="/about" component={About} />
<Route path="/about/Us" component={AboutUs} />
<Route path="/about/Company" component={AboutCompany} />
</Switch>
I would like the /about route to show about component and its children (AboutUs and AboutCompany) but the /about route is only rendering About component. How can I fix that? I have react-router 4
There are 2 ways you can achieve it.
Creating nested routes from routes.js/jsx
Creating nested routes from the parent component (about.js/jsx)
If it is from routes.js/jsx
<Switch>
<Route path="/about" component={About}>
<Route path="/about/Us" component={AboutUs} />
<Route path="/about/Company" component={AboutCompany} />
</Route>
</Switch>
If it is from routes.js/jsx
//Routes.jsx/js
<Switch>
<Route path="/about" component={About} />
</Switch>
and
//About.jsx/js
<Switch>
<Route path="/about/Us" component={AboutUs} />
<Route path="/about/Company" component={AboutCompany} />
</Switch>
<Switch>
<Route exact path="/about" component={About} />
<Route path="/about/Us" component={AboutUs} />
<Route path="/about/Company" component={AboutCompany} />
</Switch>
You need to add the exact keyword to About parent path.

How can I hide header for 404 page

<HeaderContainer>
<Switch>
<Route exact path='/counters' component={ParentCounterContainer}/>
<Route exact path='/about' component={AboutContainer} />
<Route exact path='/' component={HomeContainer}/>
<Route component={ErrorContainer} />
</Switch>
</HeaderContainer>
How can I wrap all routes except ErrorContainer in HeaderContainer?
import React from 'react';
import {Route, Redirect} from 'react-router-dom';
const CustomRoute = ({
component: Component,
...rest
}) => (
<Header />
<Route {...rest} component={(props) => {return <Component {...props} />}}/>
)
export default CustomRoute;
Try Custom Routing like this. It may work.
App router
<Switch>
<CustomRoute exact path='/counters' component={ParentCounterContainer}/>
<CustomRoute exact path='/about' component={AboutContainer} />
<CustomRoute exact path='/' component={HomeContainer}/>
<Route component={ErrorContainer} />
</Switch>
Simply put the 404 page component Route outside the HeaderContainer.
<Switch>
<HeaderContainer>
<Route exact path='/counters' component={ParentCounterContainer}/>
<Route exact path='/about' component={AboutContainer} />
<Route exact path='/' component={HomeContainer}/>
</HeaderContainer>
<Route component={ErrorContainer} />
<Switch>

Index routes with nested routes in React-router v3

I am planning to have the following route setup in my app. I am currently using React-Router 2.7.
/
/stored_systems
/stored_systems/schemas/:schema_id
/stored_systems/schemas/:schema_id/systems/:system_id
/runtime
/runtime/mainlines/:mainline_id
/runtime/mainlines/:mainline_id/valve_groups/:valve_group_id
I have written the router configuration as follows.
<Route path='/' component={App}>
<IndexRoute component={StoredSystems} />
<Route path='/stored_systems' component={StoredSystems} >
<IndexRoute component={SchemasList} />
<Route path='/stored_systems/schemas/:schema_id' component={Schema} />
<Route path='/stored_systems/schemas/:schema_id/systems/:system_id' component={System} />
</Route>
<Route path='/runtime' component={Runtime} >
<IndexRoute component={MainLinesList} />
<Route path='/runtime/mainlines/:mainline_id' component={Mainline} />
<Route path='/runtime/mainlines/:mainline_id/valve_groups/:valve_group_id' component={ValveGroup} />
</Route>
</Route>
The StoredSystems and Runtime are stateless components which basically render {props.children}.
Now, if I go to /stored_systems, it will properly render the SchemasList component. Routes like /stored_systems/schemas/schema1 would render properly.
However, if I go to /, it will render the StoredSystems component, without its children. Well, there aren't really any children defined, because it is loading an IndexRoute.
How do I render the SchemaList inside StoredSystems when I navigate to the root?
Move the / in your path and setup routes like
<Route component={App}>
<Route path = '/' component={StoredSystems} >
<IndexRoute component={SchemasList} />
</Route>
<Route path='/stored_systems' component={StoredSystems} >
<IndexRoute component={SchemasList} />
<Route path='/stored_systems/schemas/:schema_id' component={Schema} />
<Route path='/stored_systems/schemas/:schema_id/systems/:system_id' component={System} />
</Route>
<Route path='/runtime' component={Runtime} >
<IndexRoute component={MainLinesList} />
<Route path='/runtime/mainlines/:mainline_id' component={Mainline} />
<Route path='/runtime/mainlines/:mainline_id/valve_groups/:valve_group_id' component={ValveGroup} />
</Route>
</Route>

Categories