I am trying to use routing for the first time and followed the exact instructions from Udemy:
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;
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?
For React Router Version 6, your "index.js" is correct:
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" is not correct for React Router Version 6 so this is the correct one below:
*I changed 3 parts as shown below
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;
I think there are many problems that can lead to that issue.
react-router-dom version 6 no longer supports the use of components directly, use an element to specify component you route.
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;
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;
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')
);
The problem right here is that you are using React v5. Since Reacty 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 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>
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.
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;
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).
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, 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>
);
}
Yes, in react-router-dom version 6 it is a bit different. Please look as the sample below.
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
);
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.
Use:
<div>
<Header />
</div>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/profile" element={<Profile />} />
<Route path="/about" element={<About />} />
</Routes>
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;
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.
In the latest version of React, 'Switch' is replaced with 'Routes' and 'component' is replaced with 'element'