114

I am trying to use routing for the first time and followed the exact instructions from Udemy:

File App.js:

import { Route } from "react-router-dom";
import Welcome from "./Pages/Welcome";
import Game from "./Pages/Game";
import Leaderboard from "./Pages/Leaderboard";

function App() {
    return (
        <div>
            <Route path = "/welcome">
                <Welcome />
            </Route>
            <Route path = "/game">
                <Game />
            </Route>
            <Route path = "/leaderboard">
                <Leaderboard />
            </Route>
        </div>
    );
}

export default App;

File index.js

import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from "./App";

ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>,
    document.getElementById('root')
);

I get the following error:

Error: A Route is only ever to be used as the child of element, never rendered directly. Please wrap your Route in a Routes.

Where have I gone wrong?

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
Segev
  • 1,187
  • 2
  • 7
  • 6

18 Answers18

197

Yes, in react-router-dom version 6 it is a bit different. Please look as the sample below.

React Router tutorial

import { render } from "react-dom";
import {
  BrowserRouter,
  Routes,
  Route
} from "react-router-dom";
import App from "./App";
import Expenses from "./routes/expenses";
import Invoices from "./routes/invoices";

const rootElement = document.getElementById("root");
render(
  <BrowserRouter>
    <Routes>
      <Route path="/" element={<App />} />
      <Route path="expenses" element={<Expenses />} />
      <Route path="invoices" element={<Invoices />} />
    </Routes>
  </BrowserRouter>,
  rootElement
);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sachinda Nirmal
  • 2,133
  • 1
  • 8
  • 9
48

There was a fairly decent change between versions 5 and 6 of react-router-dom. It appears that the Udemy course/tutorial is using version 5 where all you needed was a Router to provide a routing context and Route components just needed to be rendered within this context. In version 6, however, the Route components now need to be rendered within a Routes component (which is an upgrade from the v5 Switch component).

Introducing Routes

One of the most exciting changes in v6 is the powerful new <Routes> element. This is a pretty significant upgrade from v5's <Switch> element with some important new features including relative routing and linking, automatic route ranking, and nested routes and layouts.

The error message is pretty clear, wrap your Route components in a Routes component. The routes also don't take children (other than other Route components in the case of nested routes), they render the components as JSX on the new element prop.

function App() {
  return (
    <div>
      <Routes>
        <Route path="/welcome" element={<Welcome />} />
        <Route path="/game" element={<Game />} />
        <Route path="/leaderboard" element={<Leaderboard />} />
      </Routes>
    </div>
  );
}
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
15

The problem is your react-router-dom version.

Probably it's 5.1 or higher.

You can try (in terminal):

npm install react-router-dom@5.3.0

And then your code will be OK. Or you better rebuild your code according to new react-router-dom.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
amir mohseni
  • 274
  • 2
  • 6
  • 4
    Guys if you are working on following some tutorials. I kindly suggest you install `npm install react-router-dom@5.3.0` , After you master **routing** you can use the latest version – Bushra Mustofa Mar 30 '22 at 11:22
11
import React from 'react'
import {BrowserRouter, Route, Routes } from 'react-router-dom'
import './App.css';


import Navbar from './components/Navbar';
import { Home } from './components/screens/Home';
import { Login } from './components/screens/Login';
import { Profile } from './components/screens/Profile';
import { Signup } from './components/screens/Signup';

function App() {
  return (
    <BrowserRouter>
    <Navbar />
    <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/login" element={<Login />} />
        <Route path="/signup" element={<Signup />} />
        <Route path="/profile" element={<Profile />} />\
    </Routes>




    </BrowserRouter>


  );
}

export default App;
  • 4
    you could elaborate, make your answer richer. You could explain the problems you devised, how your code solves them, and highlight the changes that make it work. – Marcus Vinicius Pompeu Jan 06 '22 at 23:20
  • 3
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 06 '22 at 23:21
9

In the latest version of React, 'Switch' is replaced with 'Routes' and 'component' is replaced with 'element'

Enter image description here

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mithun babu
  • 109
  • 4
6

Try to wrap your routes by Routes:

import { Route, Routes } from "react-router-dom";
import Welcome from "./Pages/Welcome";
import Game from "./Pages/Game";
import Leaderboard from "./Pages/Leaderboard";

function App() {
    return (
        <div>
          <Routes>
            <Route path = "/welcome">
                <Welcome />
            </Route>
            <Route path = "/game">
                <Game />
            </Route>
            <Route path = "/leaderboard">
                <Leaderboard />
            </Route>
           </Routes>
        </div>
    );
}

export default App;
Georgy
  • 1,879
  • 2
  • 9
  • 14
6

The problem right here is that you are using React v5. Since React v6, several changes were included in Router.

So now, to make it work, and as your error message says, you need to wrap your Route element inside a Routes element (Routes now is the equivalent, but an improved version of Switch element). Also, you need to add an "element" prop that accepts JSX instead of wrapping inside the Route element.

So, to make it work, you need to import all these elements like this:

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';

That being said, your code should look like this:

    <Router>
        <Routes>
            <Route path="/" element={<Welcome/>}>
            </Route>
            <Route path="/" element={<Game />}>
            </Route>
            <Route path="/" element={<Leaderboard />}>
            </Route>
        </Routes>
    </Router>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
6

I think there are many problems that can lead to that issue.

  1. react-router-dom version 6 no longer supports the use of components directly. Use an element to specify the component you route.

  2. Route has to be a child of Routes

Use the simple snippet.

import logo from './logo.svg';
import './App.css';
import Navbar from './components/Navbar';
import {BrowserRouter, Routes, Route, Link} from 'react-router-dom';
import Homescreen from './screens/Homescreen';


function App() {
  return (
    <div className="App">
      <Navbar/>
      <BrowserRouter>      
        <Routes>
          <Route path='/home' element={<Homescreen/>} />
        </Routes>
    
      </BrowserRouter>
     
    </div>
  );
}

export default App;
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Adesoft
  • 305
  • 3
  • 3
4

It's probably because you are using version 6 or higher of react-router-dom. Try:npm i react-router-dom@5.2.0 And it should work.

Piyush Chandra
  • 159
  • 1
  • 4
2

In the newer version of react-router-dom, we need to nest the Route inside the Routes. Also, component and exact have been removed in newer version.

codesnerd
  • 767
  • 2
  • 8
  • 23
Chethan Ck
  • 21
  • 2
2

I was facing same issue and solve it. Though I am using

react-router-dom@6

So I had to modify app.js and index.js like below

in index.js

import { BrowserRouter } from "react-router-dom";


<React.StrictMode>
<BrowserRouter>
  <App />
</BrowserRouter>
</React.StrictMode>

and app.js

import { Routes, Route } from "react-router-dom";

  function App() {
  return (
    <>
      <Header />
        <main className="py-3">
          <Container>
            <Routes>
              <Route path="/" element={<HomeScreen />} exact/>
            </Routes>
          </Container>
        </main>
      <Footer />
    </>
  );
}

export default App;

according to official documentation

Mushfiqur Rahman
  • 376
  • 1
  • 2
  • 15
1

Now, React uses React Router version 6

For React Router version 6, your index.js file is correct:

File index.js:

import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from "./App";

ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>,
    document.getElementById('root')
);

But your App.js file is not correct for React Router version 6, so this is the correct one below:

I changed three parts as shown below:

File App.js

  // 1. "Routes" is imported
import { Routes, Route } from "react-router-dom";
import Welcome from "./Pages/Welcome";
import Game from "./Pages/Game";
import Leaderboard from "./Pages/Leaderboard";

function App() {
    return (
        <div> // 2. With "<Routes></Routes>", surround "3 <Route /> tags"
            <Routes> // 3. Put an element with a component to each "<Route />"
                <Route path = "/welcome" element={<Welcome />} />
                <Route path = "/game" element={<Game />} />
                <Route path = "/leaderboard" element={<Leaderboard />} />
            </Routes>
        </div>
    );
}

export default App;
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
1

in your index.js

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root")); //where App must rendered in real DOM?in root
root.render(<App />); //jsx code is a special syntax that browser not undrestand it!

and in your App.js

import { BrowserRouter, Routes, Route } from "react-router-dom";
import AllMeetupsPage from "./pages/AllMeetups";
import NewMeetupPage from "./pages/NewMeetup";
import FavoritesPage from "./pages/Favorites";
function App() {
  return (
    <div>
      <BrowserRouter>
        <Routes>
          <Route path="/" element={<AllMeetupsPage />} />
          <Route path="/new-meetup" element={<NewMeetupPage />} />
          <Route path="/favorites" element={<FavoritesPage />} />
        </Routes>
      </BrowserRouter>
    </div>
  );
}

export default App;
Hossein Shafiei
  • 111
  • 1
  • 3
0

Use:

<div>
  <Header />
</div>
<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/profile" element={<Profile />} />
  <Route path="/about" element={<About />} />
</Routes>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • Try to wrap your routes by Routes: – Ravindu Sathsara Nov 20 '21 at 15:09
  • 2
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 20 '21 at 19:31
0

Use the element option to set your component instead of nesting it into the route tags. Then wrap all the routes with <Routes></Routes>.

Do not forget to add Routes to your imports

import { Route, Routes } from "react-router-dom";
import Welcome from "./Pages/Welcome";
import Game from "./Pages/Game";
import Leaderboard from "./Pages/Leaderboard";

function App() {
    return (
        <div>
            <Routes>
              <Route path = "/welcome" element={<Welcome />}/>
              <Route path = "/game" element={<Game />}/>
              <Route path = "/leaderboard" element={<Leaderboard />}/>
            </Routes>          
        </div>
    );
}

export default App;
isherwood
  • 58,414
  • 16
  • 114
  • 157
Clown
  • 1
  • 1
  • 2
0

I know I'm late but there is another way to do nested routes straight from javascript.

first import

import { useRoutes } from "react-router-dom";

secondly, declare your routes. Here is a quick example

function App() {

return useRoutes([
{
  path: "/",
  element: <Example/>
},
{
  path: "/contact",
  element: <Example/>
}]);

}

so now you can have unlimited nested components doing it this way.

jerryurenaa
  • 3,863
  • 1
  • 27
  • 17
0
        index.js
        
        import React from "react";
        import ReactDOM from "react-dom";
        import "./index.css";
        import App from "./App";
        import reportWebVitals from "./reportWebVitals";
        import { BrowserRouter as Router } from "react-router-dom";
        import { BrowserRouter } from 'react-router-dom';
        
        const root = ReactDOM.createRoot(document.getElementById("root"));
        root.render(
          <React.StrictMode>
            <BrowserRouter>
              <App />
            </BrowserRouter>
          </React.StrictMode>
        );
        
        reportWebVitals();
    
    import "./App.css";
    import React from "react";
    import { Routes, Route } from "react-router-dom";
    import Nav from "./Nav";
    import Home from "./Home";
    import About from "./About";
    import Winner from "./Winner";
    
    function App() {
      return (
        <Routes>
            <Route path="/" element={<Nav />} />
            <Route path="/home" element={<Home />} />
            <Route path="/about" element={<About />} />        
            <Route path="/winner" element={<Winner />} />        
        </Routes>
      );
    }
    
    export default App;


Nav.js

import React from "react";
import { Link } from "react-router-dom";


function Nav() 
{
  return (
    <div>
      <Link to="/home"> Home </Link>
      <br />
      <Link to="/about"> About </Link>
      <br />
      <Link to="/winner"> Winner List </Link>
    </div>
  );
}


export default Nav;
Keshav Gera
  • 10,807
  • 1
  • 75
  • 53
-1

There is another way to fix the version issues:

App.js File:

import { BrowserRouter, Route, Routes } from "react-router-dom";
import Welcome from "./Pages/Welcome";
import Game from "./Pages/Game";
import Leaderboard from "./Pages/Leaderboard";

function App() {
  return (<div>
  <BrowserRouter>
    <Routes>
            <Route path = "/Welcome" element={< Welcome/>}/>
            <Route path = "/Game" element={< Game/>}/>
            <Route path = "/LeaderBoard" element={< LeaderBoard/>}/>
           </Routes>
  </BrowserRouter>
    </div>
  );
}

export default App;

Index.js file:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';


ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);