DEV Community

skkyfallen
skkyfallen

Posted on

Intro to REACT-ROUTER-DOM

React Router is a client-side and server-side routing module for React, a JavaScript library for creating user interfaces. React Router works with React on the web, node.js servers, and React Native. To add the ability to route components, you'll need to import the BrowserRouter component from React Router.

The react-router-dom package makes creating new routes a breeze. To begin, you wrap the tag around the entire program. This is done so that we may access the browser's history object. Then you define your router links, as well as the components that each route will use. One of the most popular React routing frameworks is React Router. The library is built with user-friendly components to let you create a declarative routing system for your app. As a result, you can specify which of your components has a specific route. Declarative routing allows you to construct human-readable routes, making it easier to maintain your application architecture.
Note: Some components like switch are now outdated in the latest version of react-router-dom but this is just a general tutorial.

INSTALLING AND GETTING STARTED WITH REACT-ROUTER-DOM

The process of Installing react Router is very simple. I will breakdown these steps below.

  • React router can easily be installed using npm.

npm install – -save react-router-dom

  • After this is done installing you need to add its components to your react application. This is done through importing and it can be carried out by entering the following:
import {
    BrowserRouter as Router,
    Routes,
    Route,
    Link
} from 'react-router-dom';
Enter fullscreen mode Exit fullscreen mode

Now let us talk about some core components of the React-Router-Dom which we just imported.

  • Route Component: Within the Router component, we declare routes as children. We can specify as many routes as we like, but each route, path, and component (or render) must have at least two props:
import { BrowserRouter as Router, Route } from 'react-router-dom';

export default function App() {
  return (
    <Router>
      <Route path="/about" component={About} />
    </Router>
  );
}

function About() {
  return <>about</>   
}
Enter fullscreen mode Exit fullscreen mode

The path property describes where a certain route is situated in our app.

For a about page, for example, we could want the path '/about' to be accessible.

To display a specific component for our path, we use the render or component props.

Only a reference to a single component can be passed to component props, however render is more commonly used to add conditional logic to render one component or another. You can either use a reference to a component or a function to render:

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

export default function App() {
  return (
    <Router>
      <Route path="/" render={() => <Home />} />
      <Route path="/about" component={About} />
    </Router>
  );
}

function Home() {
  return <>home</>;
}

function About() {
  return <>about</>;
}
Enter fullscreen mode Exit fullscreen mode
  • Switch Component: Note: Switch is now outdated. We'll notice something very very very weird when we start adding multiple routes.

Assume we have a route for the home page and a route for the about page. Despite the fact that we define two paths, '/' and '/about,' when I visit the about page, I'll see both the home and about components.
We can fix this with the exact prop, on the home route to make sure that our router matches exactly the path '/' instead of '/about':

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

export default function App() {
  return (
    <Router>
      <Navbar />
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
      </Switch>
    </Router>
  );
}
Enter fullscreen mode Exit fullscreen mode

When it comes to switching between different routes that our router should display, there is a dedicated component called Switch that you should use if you have numerous routes in your router.

The router's switch component should be included, and we can use it to place all of our routes:

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

export default function App() {
  return (
    <Router>
      <Navbar />
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
      </Switch>
    </Router>
  );
}
Enter fullscreen mode Exit fullscreen mode

The switch component searches all of its child routes for the first one with a path that matches the current URL.

Because we have several routes and multiple plate pages in our app, but only want to show one page at a time, this component is what we want to utilize in most circumstances for most apps.

If you need numerous pages to be displayed at the same time for some reason, you might wish to skip the switch component.

  • NavLink Component: In addition, the React Router DOM provides a NavLink component, which is useful if we want to apply some custom styles.

If we're on the current path that the link points to, we can use active link styles to tell our users what page they're on just by looking at the link.

If our users are on the homepage, for example, we can inform them of this by utilizing the activeStyle prop to make our link bold and red when they're on the homepage:

import {
  BrowserRouter as Router,
  Switch,
  Route,
  NavLink
} from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Navbar />
      <Switch>
        <Route path="/" component={Home} />
        <Route path="/about" component={About} />
      </Switch>
    </Router>
  );
}

function Navbar() {
  return (
    <nav>
      <NavLink
        activeStyle={{
          fontWeight: "bold",
          color: "red"
        }}
        to="/"
      >
        Home
      </NavLink>
      <NavLink activeClassName="active" to="/about">
        About
      </NavLink>
    </nav>
  );
}
Enter fullscreen mode Exit fullscreen mode

If you don't want to include inline styles or want more reusable styles to serve the same job as activeStyle, you can set the activeClassName prop.

  • useLocation Hook: The useLocation hook has the same data as the useHistory hook.

It's worth noting that if you need both location data and history to move your user programmatically, you should useHistory. If you only require location data, you can use useLocation or get all of the location data on an object that is identical to the data provided on history. location:

import { useLocation } from "react-router-dom";


function About() {
  const location = useLocation();

  console.log(location.pathname); // '/about'

  return (
    <>
     <h1>The about page is on: {location.pathname}</h1>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode
  • useParams: When it comes to routes, one thing we didn't mention is that we can naturally design dynamic routes. This refers to routes that aren't pre-determined and can contain any amount of characters.

In circumstances where we have a blog post with a unique slug, for example, dynamic routes are useful. Given that our blog post slug can be completely different, how do we ensure that we display the relevant data and components?

A colon: must be used to declare a route parameter on a specific route. It may look like this if I wanted to establish a dynamic route for a blog post component, "/blog/:postSlug":

import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/blog/:postSlug" component={BlogPost} />
      </Switch>
    </Router>
  );
}

function Home() {
  return <>home</>;
}

function BlogPost() {
  return <>blog post</>;
}
Enter fullscreen mode Exit fullscreen mode

The relevant component, or whatever the slug is, is now being matched. But how do we get that post slug data into our BlogPost component?

Using the useParams hook, we may access any route params of a declared route and its associated component.

useParams will return an object with properties matching our route parameters (in this case, postSlug). We can use object destructuring to access and define postSlug as a variable right away:

import React from "react";
import { BrowserRouter as Router, Switch, Route, useParams } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/blog/:postSlug" component={BlogPost} />
      </Switch>
    </Router>
  );
}

function Home() {
  return <>home</>;
}

function BlogPost() {
  const [post, setPost] = React.useState(null);
  const { postSlug } = useParams();

  React.useEffect(() => {
    fetch(`https://jsonplaceholder.typicode.com/posts/${postSlug}`)
      .then((res) => res.json())
      .then((data) => setPost(data));
  }, [postSlug]);

  if (!post) return null;

  return (
    <>
      <h1>{post.title}</h1>
      <p>{post.description}</p>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)