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>
Solution 1:
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="/" />
Solution 2:
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>
)
}
Solution 3:
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>