Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
As you already know React application is a single page application. But most of the modern applications have more than a single page like about, contact, product etc. In react we can implement different pages as a different components. But there should be a way to load those individual components when the URL gets changed.
There is no inbuild routing functionality in React. But we can use third-party plugins like react-router
to do this job. There are mainly two sub-packages included in the react-route
.
react-router-native
react-router-dom
If the application focus on the web, react-router-dom
will be a choice to go.
First, install the plugin
npm install --save react-router-dom
When you installed the react-router-dom it contain react-dom and no need to do the separate installation.
Let’s create a few pages inside the application as separate components.
const AboutUs = ()=>{
return <h1>AboutUs</h1>
}
export default AboutUs;
const Profile = ()=>{
return (
<div>
<h1>Profile Page</h1>
</div>
)
}
export default Profile;
Before adding route let’s import the Profile and About pages to App.js.
Now you can use the Route component to specify the path and the component which you need to load when the user load that specific URL.
import { Route,Switch } from 'react-router-dom'
import Profile from './pages/Profile'
import AboutUs from './pages/AboutUs'
function App() {
return (
<div>
<Route path="/profile">
<Profile/>
</Route>
<Route path="/aboutus">
<AboutUs/>
</Route>
</div>
);
}
export default App;
You can either wrap the component with Route or you can set the component as a component prop in Route component.
<Route path="/profile" component={Profile}/>
One last thing you must wrap the App component with BrowserRouter in index.js. BrowserRouter use HTML5 history API which helps to keep sync your UI with the URL.
import ReactDOM from 'react-dom';
import { BrowserRouter} from 'react-router-dom'
import './index.css';
import App from './App';
ReactDOM.render(<BrowserRouter><App /></BrowserRouter>,document.getElementById('root'));
Now when you load different URLs it should show different pages in the browser.
To get started let’s create a Header component to add a Link to a different page.
//header style
.header{
background: #264653;
padding: 50px;
color: white;
}
.header a{
color: #ffe8d6;
text-decoration: none;
padding: 20px 10px;
}
import { Link} from "react-router-dom"
import classes from './MainHeader.module.css'
const MainHeader = () =>{
return (
<div className={classes.header}>
<Link to="/profile">Profile</Link>
<Link to="/aboutus">About Us</Link>
</div>
)
}
export default MainHeader
You can see we are using a Link component instead of a general HTML component.
Also, don’t forget to add the MainHeader component to App.js
function App() {
return (
<div>
<MainHeader></MainHeader>
<Route path="/profile">
<Profile/>
</Route>
<Route path="/aboutus">
<AboutUs/>
</Route>
</div>
);
}
But you see there are not any highlights that happened in the link when you move to a particular page.
Instead of Link, you can use NavLink Component to highlight the selected link. It contains activeClassName props which allow setting a particular class when the link is active.
.active-link{
background-color: #e76f51;
}
import { NavLink } from "react-router-dom"
import classes from './MainHeader.module.css'
const MainHeader = () =>{
return (
<div className={classes.header}>
<NavLink activeClassName={classes['active-link']} to="/profile">Profile</NavLink>
<NavLink activeClassName={classes['active-link']} to="/aboutus">About Us</NavLink>
</div>
)
}
export default MainHeader
If a user loads a path that does not exist it’s nice to show some sort of message. To make it work you can use Route without specifying the path prop.
const PageNotFound = ()=>{
return <h1>404</h1>
}
export default PageNotFound;
function App() {
return (
<div>
<MainHeader></MainHeader>
<Route path="/profile" component={Profile}/>
<Route path="/aboutus">
<AboutUs/>
</Route>
<Route component={PageNotFound}></Route>
</div>
);
}
Let’s say if you want to redirect the users to the about us page when users enter / as a URL. you can use the Redirect component.
function App() {
return (
<div>
<MainHeader></MainHeader>
<Route path="/profile" component={Profile}/>
<Route path="/aboutus">
<AboutUs/>
</Route>
<Route path="/" exact>
<Redirect to="/aboutus"/>
</Route>
</div>
);
}
Let’s say if you are building an e-commerce app which you need to show the different products on the same page. Usually, pass the product id from the Url and based on that you can retrieve the relevant product item.
/product/1
/product/2
For that, you can specify the path with a productId placeholder to load different products within the same ProductDetails component.
<Route path="/product/:productId">
<ProductDetails/>
</Route>
Now you can use useParams hooks to access the params in the ProductDetails component.
import { useParams } from 'react-router-dom'
const ProductDetails = ()=>{
const params = useParams();
return <div>Product {params.productId}</div>;
}
export default ProductDetails;
Let’s say we have the following two paths specified as a route.
<Route path="/profile" component={Profile}/>
<Route path="/:user" component={Profile}/>
When you load /profile in the browser you can see it shows two Profile components on the page. That happened because Route will render all the routes which match the specified Url. If you wrap the route with the Switch component it will render only the single component witch match the condition first. It behaves like a normal switch statement.
<Switch>
<Route path="/profile" component={Profile}/>
<Route path="/:user" component={Profile}/>
</Switch>