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>