By default, React comes without routing.
React Router allows us to build a single-page web application with navigation without the page refreshing when the user navigates.
Firstly, we need to create a new React app by running the following command:
npx create-react-app my-app
To install React Router, we use the following command:
npm install react-router-dom
After the installation, we can check the version of react-router-dom in package.json
file.
"dependencies": {
"react-router-dom: "^5.2.0"
}
Documentation: https://reactrouter.com/web/guides/quick-start
To use React Router in our app, we need to import the package BrowserRouter
from react-router-dom
:
import React from "react";
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
const App = () => {
return (
);
};
export default App;
To enable routing in our entire app, we need to wrap all our return into the <Router>
const App = () => {
return (
<Router>
</Router>
);
};
For example, we need to set up routings for 3 pages
Step 1: Import 3 components that will become our pages:
// Import pages
import Home from "./Home";
import About from "./About";
import Contact from "./Contact";
Step 2 Adding routes
To set up the route for the Homepage, we use path
. Here, we use / to define the path of the home page.
const App = () => {
return (
<Router>
<Route path='/'>
<Home />
</Route>
</Router>
);
};
Then, we need to add two new routes, About and Contact:
const App = () => {
return (
<Router>
<Route path='/'>
<Home />
</Route>
<Route path='/about'>
<About />
</Route>
<Route path='/contact'>
<Contact />
</Route>
</Router>
);
};
Step 3 Adding exact
keyword
Now, if we navigate to /about
or /contact
page, it will display the Homepage content as well.
Why?
With React Router, if the path matches, it will display both components.
To fix that, we need to use keyword exact
, so the Homepage route will be rendered only if it matches the full path.
<Route exact path='/'>
<Home />
</Route>
Putting it all together
import React from 'react';
// react router
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
// Import pages
import Home from './Home';
import About from './About';
import Contact from './Contact';
const App = () => {
return (
<Router>
<Route exact path='/'>
<Home />
</Route>
<Route path='/about'>
<About />
</Route>
<Route path='/contact'>
<Contact />
</Route>
</Router>
);
};
The <Switch />
component will only render the first route that matches/includes the path.
Therefore, to enhance our routing, we wrap our routes with Switch
import React from 'react';
// react router
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
// Import pages
import Home from './Home';
import About from './About';
import Contact from './Contact';
const App = () => {
return (
<Router>
<Switch>
<Route exact path='/'>
<Home />
</Route>
<Route path='/about'>
<About />
</Route>
<Route path='/contact'>
<Contact />
</Route>
</Switch>
</Router>
);
};
With our current setup, if user navigates to a nonexist page, it will just show an empty page.
It will be a better user experience if there is an 404 announcement to notify our users.
Step 1: Create an Error.js component
We add a “Back home” button for user with <Link />
.
To do that, we import <Link />
from react-router-dom
:
import { Link } from 'react-router-dom';
import React from 'react';
import { Link } from 'react-router-dom';
const Error = () => {
return (
<div>
<h1>Error Page</h1>
<Link to='/' className='btn'>
Back Home
</Link>
</div>
);
};
export default Error;
Step 2: Import Error component
import Error from './Error';
Step 3 Add the following code so non-exist pages will route to error page
<Route path='*'>
<Error />
</Route>
Putting it all together
import React from 'react';
// react router
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
// Import pages
import Home from './Home';
import About from './About';
import Contact from './Contact';
import Error from './Error';
const App = () => {
return (
<Router>
<Switch>
<Route exact path='/'>
<Home />
</Route>
<Route path='/about'>
<About />
</Route>
<Route path='/contact'>
<Contact />
</Route>
<Route path='*'>
<Error />
</Route>
</Switch>
</Router>
);
};
After setting up, if we go to /hello
page, it will direct to our 404 page.
In this example, we will create a navbar
Step 1: Import Navbar
To include the navbar in our page, we first import Navbar component
// Import navbar
import Navbar from "./Navbar";
Step 2: Place Navbar component inside the <Router />
import React from 'react';
// react router
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
// Import pages
import Home from './Home';
import About from './About';
import Contact from './Contact';
import Error from './Error';
// Import navbar
import Navbar from './Navbar';
const App = () => {
return (
<Router>
<Navbar />
<Switch>
<Route exact path='/'>
<Home />
</Route>
<Route path='/about'>
<About />
</Route>
<Route path='/contact'>
<Contact />
</Route>
<Route path='*'>
<Error />
</Route>
</Switch>
</Router>
);
};
export default App;
Step 3: Create Navbar.js
For example, we creates a navbar with 3 pages handled by the router.
Now, instead of using a traditional link attribute <a>
, we use <Link />
instead:
=> We need to import <Link />
from react-router-dom
:
import { Link } from 'react-router-dom';
import React from 'react';
import { Link } from 'react-router-dom';
const Navbar = () => {
return (
<nav>
<ul>
<li>
<Link to='/'>Home</Link>
</li>
<li>
<Link to='/about'>About</Link>
</li>
<li>
<Link to='/contact'>Contact</Link>
</li>
</ul>
</nav>
);
};
export default Navbar;
useParams hook helps us get the parameter passed on the URL without using the props object.
import React from 'react';
// react router
import { BrowserRouter as Router, Route, Switch, useParams } from 'react-router-dom';
// Import pages
import Home from './Home';
import About from './About';
import Contact from './Contact';
import Error from './Error';
// Import navbar
import Navbar from './Navbar';
function Blog() {
let { slug } = useParams();
return <div>Now showing post {slug}</div>;
}
const App = () => {
return (
<Router>
<Navbar />
<Switch>
<Route exact path='/'>
<Home />
</Route>
<Route path='/about'>
<About />
</Route>
<Route path='/contact'>
<Contact />
</Route>
<Route path="/blog/:slug">
<Blog />
</Route>
<Route path='*'>
<Error />
</Route>
</Switch>
</Router>
);
};
export default App;