React Router v6 has been released for production. At the time I am writing this post, the stable version is 6.10.0. Therefore, I will be using this version in this post. We are going to see how to set up a basic React router with React Router version 6.
First of all, you need to have React 16.8 and above to implement React Router v6 because version 6 makes use of a lot of React hooks.
If you are familiar with React Router V5, it is much easier to understand concepts in version 6. Version 6 has some major changes compared with version 5.
If you are not familiar with v5 take a look at this post first.
Table of Contents
What are the major changes between V5 and V6?
New Components in v6:
- <Routes> component: replaces <Switch> and <Route> components, providing a more intuitive way to define nested routes.
- <Route> component: now accepts the caseSensitive prop, allowing for case-sensitive route matching.
- <Link> component: now accepts the replace prop, allowing for the current URL to be replaced instead of added to the history stack.
Removed Components in v6:
- withRouter HOC: replaced with a useNavigate hook that provides similar functionality.
- <Redirect> component: replaced with the navigate function, which can be called imperatively or from a useNavigate hook.
- <Switch> component: replaced with the <Routes> component.
Setting up a basic router with V6
1. Create a React App with Vite
npm create vite@latest
Then, follow the prompts. I will be using React as the framework and JavaScript as the variant
Then, change the directory to the root folder and install react-router-dom
cd <your new project directory>
npm install react-router-dom
Delete all the files in the src folder except the App.jsx
and main.jsx
file
Now, you should basically have the following project structure.
my-react-router-app
├── node_modules
├── public
│ └── vite.svg
├── src
│ ├── components
│ │ ├── About.jsx
│ │ ├── Contact.jsx
│ │ └── Home.jsx
│ ├── App.jsx
│ └── main.jsx
├── .gitignore
├── package.json
├── README.md
└── vite.config.js
App.jsx
: The main component of the application, which renders the components for each route.main.jsx
: The entry point of the application, which renders theApp
component.
Adding code to main.jsx and App.jsx
Add the following code to the main.jsx
file
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
Replace the code in App.jsx
by the code below
src\App.jsx
import React from 'react';
import { Routes, Route } from 'react-router-dom';
import Home from './components/Home';
import About from './components/About';
import Contact from './components/Contact';
function App() {
return (
<div>
<nav>
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/about">About</a>
</li>
<li>
<a href="/contact">Contact</a>
</li>
</ul>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} />
</Routes>
</div>
);
}
export default App;
Adding components /pages
Now, we need to create three components.
create a folder named components
in the src
folder.
Add three files to the components folder: Home.jsx
, About.jsx
, and Contact.jsx
src/components/Home.jsx
import React from 'react';
function Home() {
return <h1>Home</h1>;
}
export default Home;
src/components/About.jsx
import React from 'react';
function About() {
return <h1>About</h1>;
}
export default About;
src/components/Contact.jsx
import React from 'react';
function Contact() {
return <h1>Contact</h1>;
}
export default Contact;
Now, if you run npm run dev
, you should see the demo app with three menu items: Home, About, and Contact. When you click on them, it should render the relevant component.
An Alternative approach
An alternative way to set up App.jsx
is using plain objects as follows
src\App.jsx
import React from 'react';
import { Routes, Route } from 'react-router-dom';
import Home from './components/Home';
import About from './components/About';
import Contact from './components/Contact';
const routes = [
{
path: '/',
page: <Home />
},
{
path: 'about', //you can put,for example, either "/about" or "about"
page: <About />
},
{
path: 'contact',
page: <Contact />
}
];
function App() {
return (
<div>
<nav>
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/about">About</a>
</li>
<li>
<a href="/contact">Contact</a>
</li>
</ul>
</nav>
<Routes>
{routes.map(route => (
<Route key={route.path} path={route.path} element={route.page} />
))}
</Routes>
</div>
);
}
export default App;
So, this is how you set up a very basic React Router in Version 6.
We can, however, improve this basic router by adding other React Router components.
The <Link> component
Our project structure would be something like below
You can replace the anchor tags with the <Link>
component in React Router. But, why would you do that when the anchor tag does its job?
Using the Link component in React Router v6 provides several advantages over using a standard HTML anchor tag (<a>
). It
- Allows navigation between routes without triggering a full page refresh.
- Generates the correct URL for your routes automatically, which can be helpful in more complex applications where URLs can be difficult to manage manually.
- Integrates more seamlessly with the React component model. Because
Link
is a React component, you can pass props to it as you would with any other component, and it can respond to changes in state or props. - Supports a range of additional features, such as nested routes and query parameters.
You can replace the above code with
import React from 'react';
import { Routes, Route, Link } from 'react-router-dom';
import Home from './components/Home';
import About from './components/About';
import Contact from './components/Contact';
const routes = [
{
path: '/',
page: <Home />
},
{
path: 'about', //you can put,for example, either "/about" or "about"
page: <About />
},
{
path: 'contact',
page: <Contact />
}
];
function App() {
return (
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link> //you can put,for example, either "/about" or "about".
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
</ul>
</nav>
<Routes>
{routes.map(route => (
<Route key={route.path} path={route.path} element={route.page} />
))}
</Routes>
</div>
);
}
export default App;
Should I use the element or the Component prop in <Route> Component
you can use either element or Component. But, there is a difference.
if you use element
prop, you need to use, for example, <About /> syntax. In other words, you need to create the React Element.
But, If you use Component
prop, React Router will create it for you. Therefore, you do not need to use <About />, just About
.
<Route path="about" Component={ About } />
Handling page not found errors
Our basic React Router maps three four routes:
“/”, “/home”, “/about”,”/contact”
But, what if a user enters “/whatever”? It will show you the navigation (main menu) with a blank page. This can, of course, confuse the user.
So, we need to address this situation. How can you do this?
By adding “*” for the path prop. This approach is to match any route for any undefined URLs.
Therefore, It can be used for handling page not found
errors.
Add the import
statement to App.jsx
and update the routes
object as below.
import ErrorPage from './components/ErrorPage';
const routes = [
{
path: '/',
page: <Home />
},
{
path: 'about',
page: <About />
},
{
path: 'contact',
page: <Contact />
},
{
path: '*',
page: <ErrorPage />
},
]
As you can see in the code above, I have created a new component in the src\components
folder.
src\Components\ErrorPage.jsx
import React from 'react'
function ErrorPage() {
return (
<div>404 : Page Not Found</div>
)
}
export default ErrorPage
Conclusion
React Router v6 is the latest version of the popular routing library for React applications. While there are some significant changes between v5 and v6, the basic process of setting up a router remains the same. You start by installing the react-router-dom
package and importing the necessary components, such as BrowserRouter
, Route
, and Link
.
In v6, you can use the Link
component to create links to different pages in your application. When defining routes, you can use either an element or a component prop to render the content of the page.
Handling 404 errors has also become easier in v6. Instead of using a separate Switch
component to handle 404 errors, you can simply define a <Route path="*" element={<ErrorPage />} />
route at the end of your routes to handle all unmatched paths.
Overall, React Router v6 offers an improved and simplified API that makes it easier to create complex routing structures in your React applications.