DEV Community

g4rry420
g4rry420

Posted on • Updated on

Routing using react-router-dom

In this post, I will talk about routing using react-router-dom in the react applications.
But, first, question arises, Why do we need to use routing in react ? And maybe you don't know what is React ?

What is React ?

React is a javascript framework that is developed and maintained by Facebook by providing single page applications.

Single Page Applications (SPA)?

In the early development of web applications, whenever a user clicks on a new page link, then the client side of the browser sends data to server and grabs a particular html file related to the link and reloads the page which takes time.

But with implementation of SPA, user only has one index.html file and whenever user clicks on a new link, the data re-renders on the same page without grabbing the entire new html file.

Why do we use routing in react ?

Since we are in the world of SPA, the routing helps us to display some template and hide another template based on the route.

Okay, I hope you know understand the use of routing in SPA.

Let's dive into the coding part of the simple project we are going to make to understand about react-router-dom.

Create React Application

Create a new react app named routing. Run the below command in your command prompt, terminal or git bash.
npx create-react-app routing
cd routing
npm start or yarn start

By running the about commands, your project is now on the localhost:3000

Installing react-router-dom

To install react-router-dom in your app, simply run npm i react-router-dom or yarn add react-router-dom.

Folder structure

You folder structure should look like this. Delete unnecessary files.

folder structure

And make sure to remove all the content from App.css file.

Adding New Route

Before creating a route lets make two new components, home.js and room.js

home.js should look like this.

import React from 'react'

export default function Home() {
    return (
        <div>
            Welcome to the Home.
        </div>
    )
}

Enter fullscreen mode Exit fullscreen mode

room.js should look like this.

import React from 'react'

export default function Room() {
    return (
        <div>
            Welcome to the Room.
        </div>
    )
}
Enter fullscreen mode Exit fullscreen mode

Next your App.js should look like this.

import { BrowserRouter, Route } from "react-router-dom"

import './App.css';
import Home from "./home";
import Room from "./room"

function App() {
  return (
    <div className="App">
      <BrowserRouter>
        <Route path="/" component={Home} />
        <Route path="/room" component={Room} />
      </BrowserRouter>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Understanding react-router-dom terms

In the App.js, I take BrowserRouter and Route from the react-router-dom.

BrowserRouter is a top level components which basically lets us start using routing in our react application. So make sure that you wrap all your components inside this.

Route basically, tells the react-router that components in this are going to be on different pages.So, in this case, Home and Room are the one.

Now, if you go to your browser you should see this.
browser

In your navigation, you should link to /room to visit different page template. And you should see this.
Alt Text

Confused ??
Don't worry I will tell you why this happened.

If you see our App.js,

import { BrowserRouter, Route } from "react-router-dom"

import './App.css';
import Home from "./home";
import Room from "./room"

function App() {
  return (
    <div className="App">
      <BrowserRouter>
        <Route path="/" component={Home} />
        <Route path="/room" component={Room} />
      </BrowserRouter>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

You can see that "/" path represents Home component and "/room" path represents Room component.
So, when I changed the path from "/" to "/room" both Home and Room both components got rendered.
To render only one component at a time, we can use exact prop in the Route like this.

<Route exact path="/" component={Home} />
<Route path="/room" component={Room} />
Enter fullscreen mode Exit fullscreen mode

And Now our localhost only renders one page at a time. Like this.
Alt Text

However, we can achieve the above goal by getting the Switch from the react-router-dom.

import { BrowserRouter, Route, Switch } from "react-router-dom"
Enter fullscreen mode Exit fullscreen mode

Switch make sures that only one components loads at one time.

import { BrowserRouter, Route, Switch } from "react-router-dom"

import './App.css';
import Home from "./home";
import Room from "./room"

function App() {
  return (
    <div className="App">
      <BrowserRouter>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/room" component={Room} />
        </Switch>
      </BrowserRouter>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Adding Navigation Links

Now, we need to click something so that we can change routes. For react-router gives us the Link and NavLink.
Import these into App.js.

import { BrowserRouter, Route, Link, NavLink } from "react-router-dom"
Enter fullscreen mode Exit fullscreen mode

However, Behind the scenes, the Link and NavLink are simply anchor tags.
But the difference between two is that NavLink comes with a class of active whereas Link does not.

Okay, Now add links to our application.

import { BrowserRouter, Route, Link, NavLink } from "react-router-dom"

import './App.css';
import Home from "./home";
import Room from "./room"

function App() {
  return (
    <div className="App">
      <BrowserRouter>
        <div>
          <nav>
            <Link to="/">Home</Link>
            <NavLink to="/room">Room</NavLink>
          </nav>
          <Route exact path="/" component={Home} />
          <Route path="/room" component={Room} />
        </div>
      </BrowserRouter>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Now if you click on different links you can navigate to different pages.

Nested Routing

Nested Routing in the components is bit tricky to manage.But don't worry I will tell you the way which I found most easy for this and this is the way that they recommend in the react-router-dom documentation.

So, Suppose you want to have route like this "/room/room1". I mean there could be multiple rooms inside the room route.

Okay, Now , create new file called room-container.js and it should look like this:

import React from 'react'
import { Route, Link  } from "react-router-dom"
import Room from './room'
import RoomId from './room-id'

export default function RoomContainer(props) {
    return (
        <div>
            <Link to={`/room/${Math.random()}`}> Link to different Nested Rooms </Link>
            <div>
                <Route exact path="/room" component={Room} />
                <Route path="/room/:roomId" component={RoomId} />
            </div>
        </div>
    )
}
Enter fullscreen mode Exit fullscreen mode

Now in your App.js, instead of importing room.js file you should import room-container.js file and in your room-container.js file you should import room.js

Oh God, I hope I didn't make it much confusing.

Your App.js file should look like:

import { BrowserRouter, Route, Link, NavLink } from "react-router-dom"

import './App.css';
import Home from "./home";
import RoomContainer from "./room-container"

function App() {
  return (
    <div className="App">
      <BrowserRouter>
        <div>
          <nav>
            <Link to="/">Home</Link>
            <NavLink to="/room">Room</NavLink>
          </nav>
          <Route exact path="/" component={Home} />
          <Route path="/room" component={RoomContainer} />
        </div>
      </BrowserRouter>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Now, you might be wondering why did we follow this structure.Actually, this is the structure that the react-router-dom documentation recommends us to implement to correctly achieve nested routing.

Now, in your room-container.js, you might wondering about these lines of code,

<Link to={`/room/${Math.random()}`}> Link to different Nested Rooms </Link>
<Route path="/room/:roomId" component={RoomId} />
Enter fullscreen mode Exit fullscreen mode

First line of code is the link to nested route and in the second the line ":roomId" defines that the this value is gonna be dynamically put here. ":roomId" is know as the params for the nested route link.

Actually, this is the way we implement nested route to a component. And in this case I have created a new file called room-id.js and it should look like this:

import React from 'react'

export default function RoomId(props) {
    return (
        <div>
            Welcome to Room Id:   

            {
                props.match.params.roomId
            }
        </div>
    )
}

Enter fullscreen mode Exit fullscreen mode

Now, if click on the Room and then click on to the Link to different Nested Rooms, you will be routed to the different routes.And you can see the roomId for it in the room-id.js component.

Understanding terms and Some theory

Whenever you define a in the and the component in it has props of the route which can be useful to us.
For example: In the room-id.js, I can access and display the roomId using the props.match.params.roomId.

Similarily these props are also presented in the room-container.js and to maintain consisitency in our application, most developers prefer to use them instead of hard-coding the routes like these:

 <Link to={`/room/${Math.random()}`}> Link to different Nested Rooms </Link>
            <div>
                <Route exact path="/room" component={Room} />
                <Route path="/room/:roomId" component={RoomId} />
            </div>
Enter fullscreen mode Exit fullscreen mode

We can implement the same thing like this:

 <Link to={`${props.match.url}/${Math.random()}`}> Link to different Nested Rooms </Link>
            <div>
                <Route exact path={`${props.match.path}`} component={Room} />
                <Route path={`${props.match.path}/:roomId`} component={RoomId} />
            </div>
Enter fullscreen mode Exit fullscreen mode

props.match.path represents the path that is relative to the parent container, the user is currently on.
props.match.url represents the matched portion of the url.

Conclusion

We have seen how we can implement react routing in react application and also we got to know about the nested routing.

I know nested routing might seems confusing for the beginner but if you understand it by implementing it on a project you will get it.

Thanks for reading.
Happy Coding:)

Top comments (2)

Collapse
 
vaiofficial profile image
Vaiofficial

route is not working in my editor , please help me guys

Collapse
 
shreyvijayvargiya profile image
shrey vijayvargiya

Stackoverflow and Chat GPT can be those guys