How to Utilize React Router in ReactJS Application

This modern web application plays a vital role in page navigation and better user experience.

Thiyagaraj Suthagar

Thiyagaraj Suthagar

Programmer Analyst
Thiyagaraj Suthagar

Latest posts by Thiyagaraj Suthagar

ReactJS is the JavaScript library for building interactive user interfaces. React Router is the routing library, which is the declarative routing in ReactJS, containing three types of components such as Router, Route and Navigation Components. Before React Router V4, it is static and after V4 Dynamic. These components should be imported from ‘react-router-dom’.

To install run the following command, 

npm install react-router-dom

Using React -Router we can achieve the following 

  • URL/Path and component mapping.  
  • Can track browser history since it has history objects.
  • Navigation of pages back and forward and vice versa.

import { BrowserRouter, Route, Link } from “react-router-dom”

Router Component

  • <BrowserRouter>: It can be used when we have service calls request.
  • <HashRouter>: It can be used when we use static file server.

But, both routers will create history object which can be created as mentioned below.

import browserHistory from ‘history/createBrowserHistory’
export default const history=browserHistory();

import { BrowserRouter } from “react-router-dom”
ReactDOM.render(
  <BrowserRouter history={history}>
    <App />
  </BrowserRouter>, document.getElementById(‘root’)
);

import { HashRouter } from “react-router-dom”
ReactDOM.render(
  < HashRouter history={history}>
    <App />
  </ HashRouter >, document.getElementById(‘root’)
);

Route Matching Component

Route matching is nothing, but comparing <Route> path to the current location pathname. If it matches then will load its content else returns null. It contains two components as follows:

  • <Route>: Path and component props should be added.
  • <Switch>: It’s useful for grouping routes. It will iterate through child route elements and render the route element which is matching to the current path/location.

import {Route, Switch} from “react-router-dom”;

<Route path=’/about’ component= {About}/> // renders <About/>
<Route path=’/contact’ component= {Contact}/> // renders null
<Route component= {Always}/> // renders <Always/>

<Switch>
<Route exact path=”/” component= {Home} />
<Route path=”/about” component= {About} />
<Route path=”/contact” component= {Contact} />
<Route component= {NoMatch} />
</Switch>

Component in the Route could be state component (Class Component) or stateless function component.

Location

Typically you only have access to the location in Route Components. It provides the location anywhere in your app with a child render prop.

<Location>
  {props => {
    props.location
    props.navigate
  }}
</Location>

CreateHistory

Creates a history object that enables you to listen for location changes. You don’t typically need this outside of some types of testing.

{ createMemorySource, createHistory} from “@reach/router”

// listen to the browser history
let history = createHistory(window)

// for some types of tests you want a memory source
let source = createMemorySource(“/starting/url”)
let history = createHistory(source)

LocationProvider

Sets up a listener to location changes. The history property is to listen. Defaults to the browser history or a memory history if a DOM is not found.

import { createMemorySource, createHistory, LocationProvider} from “@reach/router”;

let history = createHistory(window)
let source = createMemorySource(“/starting/url”)
let history = createHistory(source)

let App = () => (
  <LocationProvider history= {history}>
   <div>
      Alright, we’ve established some location
      context
    </div>
  </LocationProvider>

)

ServerLocation

When server rendering, you need to wrap your app in a ServerLocation. This enables your Routers, Links, etc. to match a location on the server where there is no history to listen to.

const App = () => (
<Router>
<Home path=”/” />
<Group path=”/groups/: groupId” />
</Router>)
const markup = renderToString (
<ServerLocation url=”/groups/123″>
<App />
</ServerLocation>
)

IsRedirect

Returns true if the error is a redirect request. Useful for server rendering and rethrowing errors in componentDidCatch.

import { isRedirect } from “@reach/router”

class Decent extends React.Component {
  componentDidCatch(error) {
    if (isRedirect(error)) {
      throw error
    } else {
     // do whatever you were going to do
    }
  }
}

RedirectTo

Imperatively redirects to a new location by throwing a redirect request in React 16+ only.

import { redirectTo } from “@reach/router”

class User extends React.Component {
  componentDidMount() {
    fetchUser().then(user => {
      if (user.optedIntoNewUI) {
        redirectTo(“/the/new/digs”)
      }
    })
  }
}

URL Parameter

We can pass parameter through URL. In the below example passing invoice Id as parameter.

const Invoice = props => (
  <div>
    <h2>Invoice {props.invoiceId} </h2>
  </div>
)
<Router>
  <Invoice path=”invoices/: invoiceId” />
</Router>
<Link to=”invoices/123″>Invoice 123</Link>
<Link to=”invoices/abc”>Invoice ABC</Link>

Redirect

Redirects from one path to another. Use this when you want to change a URL without breaking links to the old path.

<Router>
  <Redirect from=”aboutus” to=”about-us” />
  <AboutUs path=”about-us” />

  <Redirect from=”users/:userId” to=”profile/:userId” />
  <Profile path=”profile/:userId” />
</Router>

Match

Matches a path to the location and calls back with a match or null. Matching is relative to any parent Routers, but not parent Match’s, because they render even if they don’t match.

import { Match } from “@reach/router”
const App = () => (
  <Match path=”/hot/:item”>
    {props => props.match ? ( <div>Hot {props.match.item}</div> ) : ( <div>Uncool</div> ) }
  </Match>)

Navigate

If you need to navigate programmatically (like after a form submits), import navigate.

import { navigate } from “@reach/router”

const Invoices = () => (
  <div>
    <NewInvoiceForm onSubmit={async event => { const newInvoice = await createInvoice ( event.target )
        Navigate (`/invoices/${newInvoice.id}` )
      }} />
  </div>
)

Navigation Component

React Router provides <Link> component to create links in the application and which will be rendered as <a> anchor in the page.

<Link to=”/”>Home</Link>

<NavLink> is a special type of <Link> which can style itself as “active” when their prop matches the current location.

<NavLink to=”/react” activeClassName=”hurray”> React </NavLink>

And also we can use <Redirect> component for page transition.

<Redirect to=”/login” />

Types of React-Router

  1. Default Routes
  2. Nested Routes
  3. Index Routes
  4. Multiple Router

Default Routes

Below is the example for default or basic routing.

const routing = (
  <Router>
   <div>
      <Route path=”/” component={App} />
      <Route path=”/users” component={Users} />
      <Route path=”/contact” component={Contact} />
    </div>
  </Router>
)

ReactDOM.render (routing, document.getElementById(‘root’))

Nested Routing

When you render a router, you can nest routes inside other routes and the paths and the render tree will be nested as well.

<Router>
  <Root path=”/”>
    <Home path=”/” />
    <Dashboard path=”dashboard”>
      <DashboardHome path=”/” />
      <Trends path=”trends” />
      <Graphs path=”graphs” />
   </Dashboard>
    <Team path=”team”>
      <TeamHome path=”/” />
     <Profile path=”:userId” />
    </Team>
  </Root>
</Router>

Index Routes

Index Routes are just another child of a route, except their path is /. An Index Route will render when no other sibling matches the location.

const InvoicesIndex = () => (
  <div>
    <p>
      Maybe put some pretty graphs here or something.
    </p>
  </div>
)
<Router>
  <Invoices path=”invoices”>
    <InvoicesIndex path=”/” />
    <Invoice path=”:invoiceId” />
  </Invoices>
  {/*…*/}
</Router>

Multiple Router

Multiple routers can be used in the Application like for Menus, Sidebar etc. Below is the example.

{/* a router for the sidebar */}
<Sidebar>
<Router>
<HomeNav path=”/*” />
<DashboardNav path=”dashboard/*” />
</Router>
</Sidebar>

{/* a router for the main screen */}
<MainScreen>
<Router>
<Home path=”/” />
<About path=”about” />
<Support path=”support” />
<Dash path=”dashboard”>
<DashHome path=”/” />
<Invoices path=”invoices” />
<Team path=”team” />
</Dash>
</Router>
</MainScreen>

Embedded Router

Embedded Routers are any Routers you render deeper inside your app beneath another router.

const App = () => (
<div>
<nav>
<Link to=”/”>Home</Link> – {” “}
<Link to=”dashboard”>Dashboard</Link>
</nav>
<Router>
<Home path=”/” />
<Dashboard path=”dashboard/*” />
</Router>
</div>
);

const Dashboard = () => (
<div>
<h2>Dashboard</h2>
<nav>
<Link to=”./”>Dashboard Home</Link> – {” “}
<Link to=”team”>Team</Link> – {” “}
<Link to=”projects”>Projects</Link>
</nav>

<Router>
<DashboardHome path=”/” />
<Team path=”team” />
<Projects path=”projects” />
</Router>
</div>
);

const Home = () => <h2>Home</h2>;
const DashboardHome = () => <h2>Dashboard Home</h2>;
const Team = () => <h2>Team</h2>;
const Projects = () => <h2>Projects</h2>;

render(<App/>, document.getElementById(“root”));

Active Link

Active link is shown as Red color when the user clicks on the Nav link.

const NavLink = props =>
<Link
{…props}
getProps={({ isCurrent }) => {
return {
style: {
color: isCurrent ? “red” : “blue”
}
};
}}
/>
);

const App = props => (
<div>
<Logo />
<h1>Active Links</h1>
<nav>
<NavLink to=”/”>Home</NavLink> <NavLink to=”/about”>About</NavLink>
</nav>
{props.children}
</div>
);

const Home = () => (
<div>
<h2>Home</h2>
</div>
);

const About = () => (
<div>
<h2>About</h2>
</div>
);

Render (
<Router>
<App path=”/”>
<Home path=”/” />
<About path=”about” />
</App>
</Router>, document.getElementById (“root”));

Relative Links

Links can have a relative “to” prop.

const assignments = [
{ id: “abc”, name: “Mid-Term Paper” },
{ id: “123”, name: “Chapter 4 Quiz” }];

const Root = () => (
<Router>
<App path=”/”>
<Assignments path=”assignments”>
</Assignments>
</App>
</Router>
)

const App = ({ children }) => (
<div>
<Logo />
<nav>
<Link to=”assignments”>Assignments</Link>
</nav>
{children}
</div>
);

const Assignments = props => (
<div>
<h2>Assignments</h2>
<ul role=”navigation”>
{assignments.map (assignment => (
<li>
<Link to={assignment.id}>{assignment.name}</Link>
</li>
))}
</ul>
{props.children}
</div>);
const Assignment = props => {
const assignment = assignments.find(a => a.id === props.assignmentId);
return (
<div>
<h3>{assignment.name}</h3>
</div>
);
};
render (<Root/>, document.getElementById(“root”));

Conclusion 

To sum up React Router: it’s a different kind of routing, primary API and additional API such as location, locationProvider, serverLocation and redirectTo etc.

Share This Article


Thiyagaraj Suthagar

Thiyagaraj Suthagar

Programmer Analyst
Thiyagaraj Suthagar

Latest posts by Thiyagaraj Suthagar

No Comments

Post A Comment