Route renders wrong component, ReactJS - javascript

I am trying to access the FolderDetail component once the url /folders/xy is called. Instead of getting FolderDetail component I always get the Folders component which lies in /folders... Please help.
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<div className="App">
<Navigation />
<Switch>
<Route path="/" component={Home} exact />
<Route path="/folders" component={Folders} />
<Route path="/folders/:id" component={FolderDetail} />
<Route path="/login" component={Login} />
</Switch>
</div>
</BrowserRouter>
);
}
export default App;

You should add exact to all Routes components, this is a working codesandbox :
const App = () => {
return (
<BrowserRouter>
<div className="App">
<Navigation />
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/folders" component={Folders} />
<Route exact path="/folders/:id" component={FolderDetail} />
</Switch>
</div>
</BrowserRouter>
);
};

A switch takes the firs matched route so you need to reorder your routes like this, (also add exact)
<Switch>
<Route exact path="/folders/:id" component={FolderDetail} />
<Route exact path="/folders" component={Folders} />
<Route exact path="/login" component={Login} />
<Route exact path="/" component={Home} exact />
</Switch>
Always put the more specific routes first.

Related

Why are my React components rendering in all routes?

This is the my App() function in App.js, the comps :"Sidebar, Feed and Widgets" keeps rendering in route ="/" and also ="/login" as well, in addition to that "Login" comp didn't even render in route ="/login".
<Router>
<div className="app">
<Switch>
<Route path="/">
<Sidebar />
<Feed />
<Widgets />
</Route>
<Route path="/login">
<Login />
</Route>
</Switch>
</div>
</Router>
If you are using the latest version of react-router-dom, you must change the Switch to Routes
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import { Sidebar, Feed, Widgets } from '...'
const Home = () => {
return (
<Sidebar />
<Feed />
<Widgets />
)
}
const App = () => {
return (
<Router>
<div className="app">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/login" element={<Login />} />
</Routes>
</div>
</Router>
)
}
You need to add exact with "/'" route.
In your case when you are not adding exact, React router will match '/login' path with the first path '/' and will render accordingly without checking next routes. By adding exact, first '/' will not match and it will match with second route '/login'.
<Router>
<div className="app">
<Switch>
<Route path="/" exact>
<Sidebar />
<Feed />
<Widgets />
</Route>
<Route path="/login">
<Login />
</Route>
</Switch>
</div>
</Router>
For more information, you can also refer this similar question: React : difference between <Route exact path="/" /> and <Route path="/" />
The Switch component exclusively matches and renders routes, so only 1 route can ever be matched. You've an issue with the order of your routes though, so only the "/" path matches since it's earlier and is rendered. The route for "/login" can never be reached, as-is.
In other words, this means is that when the path is "/login" that "/" still matches it and is the route rendered. In react-router-dom v5 think of the path props as a "path prefix".
In the Switch component, path order and specificity matter! You should order the paths from more specific to less specific. This allows more specific paths like "/login" to be matched before trying the less specific paths.
<Router>
<div className="app">
<Switch>
<Route path="/login">
<Login />
</Route>
<Route path="/">
<Sidebar />
<Feed />
<Widgets />
</Route>
</Switch>
</div>
</Router>

React Router with other components

I have one problem that I can not understand. I am totally a beginner in ReactJS so I hope you will help me. I made Navigation with React Router and it works, but when I start to render all other components in App.js nothings happened. When I am routing through the navigation bar it is rendering, but on scroll, nothing happened.
This is my App.js without rendering other components that work normally, but when I add something like , it is the same without scroll.
my code :
const App = () => {
return (
<div>
<Router>
<Topbar />
<About />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/service" component={Service} />
<Route path="/portfolio" component={Portfolio} />
<Route path="/contact" component={Contact} />
</Switch>
</Router>
</div>
);
};
export default App;
You need to use a redirect
1/ import {Redirect} from 'react-router-dom';
2/ Change your Home route to <Route exact path="/home" component={Home} />
3/ Add the redirect (It must be the last route)
<Route exact path="/">
<Redirect to="/home" />
</Route>
Example :
import React from 'react';
import {
BrowserRouter as Router,
Route,
Switch,
Redirect
} from 'react-router-dom';
import Home from './Home';
import About from './About';
import Service from './Service';
import Portfolio from './Portfolio';
import Contact from './Contact';
const App = () => {
return (
<Router>
<Switch>
<Route path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/service" component={Service} />
<Route path="/portfolio" component={Portfolio} />
<Route path="/contact" component={Contact} />
{/* Redirect */}
<Route exact path="/">
<Redirect to="/home" />
</Route>
</Switch>
</Router>
);
};
export default App;
If you want to check a demo : Stackblitz

How to have react load Home page and then route to others

I have a basic portfolio app that has the following structure:
App.js
function App() {
return (
<BrowserRouter>
<LeftNav />
<RightNav />
<NavBar />
<Switch>
<Route component={Home} path='/' exact />
<Route component={About} path='/about' />
<Route component={Project} path='/projects' />
<Route component={Contact} path='/contact' />
</Switch>
</BrowserRouter>
)
}
When I click on the link to go the production site it only renders the LeftNav, RightNav, and Navbar. I have to click on the Home component to have the Home Screen load.
I then tried putting the Home component outside of to look like:
function App() {
return (
<BrowserRouter>
<LeftNav />
<RightNav />
<NavBar />
<Home />
<Switch>
<Route component={Home} path='/' exact />
<Route component={About} path='/about' />
<Route component={Project} path='/projects' />
<Route component={Contact} path='/contact' />
</Switch>
</BrowserRouter>
)
}
This is the action I want upon clicking on the link, however then my components don't load. How do I structure this so that the Home component loads up on the initial click and that I'm able to navigate to other pages?
Your first version is good, just add a redirect and change the home path
import React from 'react';
import {BrowserRouter, Switch, Route, Redirect} from 'react-router-dom'; // import Redirect
function App() {
return (
<BrowserRouter>
<LeftNav />
<RightNav />
<NavBar />
<Switch>
<Route component={Home} path='/home' exact /> // change the path
<Route component={About} path='/about' />
<Route component={Project} path='/projects' />
<Route component={Contact} path='/contact' />
<Route path="/" exact> // Add the redirect
<Redirect to="/home" />
</Route>
</Switch>
</BrowserRouter>
)
}
You will have to exchange your home path from being the default page:
<Route component={Home} path='/' exact />
to
<Route component={Home} path='/home' exact />
and then add a 'Redirect' to your App.js :
<Route path="/" exact>
<Redirect to="/home" />
</Route>

React router always display at the bottom the Error page

I'm having a problem regarding using of error page in my react app. The 404 page always shows at the bottom of every page that I render. I'm new to react. I hope someone can help me.
This is my App.js
import {BrowserRouter as Router,Switch,Route} from 'react-router-dom';
import Login from './components/auth/Login';
import Register from './components/auth/Register';
import ErrorPage from './components/ErrorPage';
import Order from './components/Order';
import Navbar from './components/partials/Navbar';
import Footer from './components/partials/Footer';
import Shop from './components/Shop';
import ItemDetails from './components/ItemDetails';
import Cart from './components/Cart';
import Customize from './components/Customize';
const App = () => {
return (
<>
<Router>
<Switch>
<Route exact path='/login'>
<Login />
</Route>
<Route exact path='/register'>
<Register />
</Route>
<div>
<Navbar />
<Route exact path='/'>
<Shop />
</Route>
<Route exact path='/order'>
<Order />
</Route>
<Route exact path='/item/details'>
<ItemDetails />
</Route>
<Route exact path='/cart'>
<Cart />
</Route>
<Route exact path='/customize'>
<Customize />
</Route>
<Route component={ErrorPage} />
</div>
</Switch>
</Router>
<Footer />
</>
);
}
export default App;
I searched about handling error page in react and I see that the order of routes is important but I don't get why I'm still getting the error page even it's in the bottom. Thank you guys.
That's because the switch component returns the first child at the root that meets the path condition. If the path condition doesn't exist it's evaluated as true. In your case you have 3 child Login, Register and the div which will always be evaluated to true. So just move all routes to the root of your switch:
<Router>
<Switch>
<Route exact path='/login'>
<Login />
</Route>
<Route exact path='/register'>
<Register />
</Route>
<div>
<Navbar />
<Switch>
<Route exact path='/'>
<Shop />
</Route>
<Route exact path='/order'>
<Order />
</Route>
<Route exact path='/item/details'>
<ItemDetails />
</Route>
<Route exact path='/cart'>
<Cart />
</Route>
<Route exact path='/customize'>
<Customize />
</Route>
<Route component={ErrorPage} />
</Switch>
</div>
</Switch>
</Router>

route redirects to nothing react-router 4 [duplicate]

This question already has answers here:
Route is not matched
(3 answers)
Closed 5 years ago.
I'm not sure why everything is redirecting to a blank page:
I'm using:
"react-router": "^4.2.0",
"react-router-dom": "^4.1.1",
App.js
import { BrowserRouter, Route, Switch } from 'react-router-dom';
class Container extends Component{
render() {
return (
<div>{this.props.children}</div>
);
}
}
export default class App extends Component {
render() {
return (
<BrowserRouter onUpdate={onUpdate}>
<Switch>
<Route component={HomePageContainer} exact path="/" />
<Route component={CompanyDetailContainer} name="companydetail" path="interviews/companies/:companyId/details" />
<Route component={InterviewContainer} name="interview" path="interviews/companies/:companyId" />
<Route component={Container} path="/" />
<Route component={NotFound} path="*" />
</Switch>
</BrowserRouter>
);
}
}
Homepage route to '/' is working fine.
What's not working are all the other routes.
For example when a user clicks a hyperlink that redirects to these routes or other routes other than the default route, I'm getting a blank page:
<Route component={CompanyDetailContainer} name="companydetail" path="interviews/companies/:companyId/details" />
<Route component={InterviewContainer} name="interview" path="interviews/companies/:companyId" />
Here is how my routes were working when I was using react-router v3:
<Router history={browserHistory} onUpdate={onUpdate}>
<Route path="/">
<IndexRoute component={HomePageContainer} />
<Route component={InterviewContainer} name="interview" path="interviews/companies/:companyId" />
<Route component={About} name="about" path="about" />
<Route component={JobList} name="jobs" path="jobs" />
</Route>
<Route component={Container} path="/" />
<Route component={NotFound} path="*" />
</Router>
Note that I also added the new route for companydetail just recently.
All your paths needs to be with respect to to base path i.e. /
Change your router config to
<Switch>
<Route component={HomePageContainer} exact path="/" />
<Route component={CompanyDetailContainer} name="companydetail" path="/interviews/companies/:companyId/details" />
<Route component={InterviewContainer} name="interview" path="/interviews/companies/:companyId" />
<Route component={Container} path="/" />
<Route component={NotFound} path="*" />
</Switch>
Try wrapping your router in an anonymous function.
const App = () => (
<BrowserRouter onUpdate={onUpdate}>
<Switch>
<Route component={HomePageContainer} exact path="/" />
<Route component={CompanyDetailContainer} name="companydetail" path="interviews/companies/:companyId/details" />
<Route component={InterviewContainer} name="interview" path="interviews/companies/:companyId" />
<Route component={Container} path="/" />
<Route component={NotFound} path="*" />
</Switch>
</BrowserRouter>
)

Categories

Resources