React Router

React Router

Reactjs series from beginner to advanced level ep10

React Router is a popular library for routing in React applications. It allows developers to define and manage different routes and paths within a React application, and provides tools to navigate between these routes. This makes it easier to create single-page applications (SPAs) with dynamic and interactive content, without requiring a page refresh. React Router also provides components for handling links, navigating programmatically, and rendering dynamic content based on the current URL.

Let's consider a scenario where we are building a simple e-commerce website using React. We want to have different pages for the homepage, product listings, and a product detail page.

With React Router, we can define these routes in our application and assign a component to each route. For example, we can define a route for the homepage as '/' and assign a Home component to it. Similarly, we can define a route for the product listings as '/products' and assign a Products component to it. And for the product detail page, we can define a route as '/products/:id' and assign a ProductDetail component to it. The ':id' part of the URL is a dynamic parameter that can change based on the selected product.

Now, when a user visits the website, React Router takes care of matching the URL to the appropriate route and rendering the corresponding component. For example, when the user visits the homepage at '/', React Router will render the Home component. When the user clicks on a product listing, the URL will change to '/products/:id' and React Router will render the ProductDetail component, passing the 'id' parameter as a prop to the component.

In this way, React Router makes it easy to manage different pages and routes within a React application, and provides a seamless experience for users navigating between these pages.

Installing and using react router

To install React Router, you need to run the following command in your terminal:

npm install react-router-dom

Using React Router:

Once you have installed React Router, you can start using it in your React application by importing the BrowserRouter and Route components from the react-router-dom library.

Here is an example of how you can use React Router to create a basic navigation system in your React application:

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

import Home from "./components/Home";
import Products from "./components/Products";
import About from "./components/About";

const App = () => {
  return (
    <Router>
      <Route exact path="/" component={Home} />
      <Route path="/products" component={Products} />
      <Route path="/about" component={About} />
    </Router>
  );
};

export default App;

In this example, we have defined three routes:

  1. The root route, which is defined as <Route exact path="/" component={Home} /> and corresponds to the homepage.

  2. The products route, which is defined as <Route path="/products" component={Products} /> and corresponds to the products page.

  3. The about route, which is defined as <Route path="/about" component={About} /> and corresponds to the about page.

The BrowserRouter component is used to wrap the routes, which makes sure that the routes are updated whenever the URL changes. The Route component takes in two properties: path and component. The path property defines the URL path that the route corresponds to, and the component property defines the React component that should be rendered for this route.

With this setup, React Router takes care of matching the URL to the appropriate route and rendering the corresponding component, providing a seamless navigation experience for users

The Root Route

The root route, also known as the base route, refers to the main or default route in a React Router configuration. It is usually defined with the path '/' and corresponds to the homepage or the main page of an application. The root route is typically the first route defined in the React Router configuration and acts as a starting point for navigation in the application. All other routes are defined relative to the root route and can be accessed by appending a path to the root route URL.

Consider a simple React application that has a homepage and a products page. The root route could be defined as follows:

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

import Home from "./components/Home";
import Products from "./components/Products";

const App = () => {
  return (
    <Router>
      <Route exact path="/" component={Home} />
      <Route path="/products" component={Products} />
    </Router>
  );
};

export default App;

In this example, the root route is defined as <Route exact path="/" component={Home} />. This means that when the user visits the URL http://example.com/, React Router will render the Home component. The exact property is used to ensure that only this exact path is matched and no other route with a similar prefix will be considered.

The products route is defined as <Route path="/products" component={Products} />. This means that when the user visits the URL http://example.com/products, React Router will render the Products component.

In this way, the root route acts as the starting point for the navigation in the application, and all other routes are defined relative to it. The React Router library takes care of matching the URL to the appropriate route and rendering the corresponding component. This makes it easy to manage different pages and routes within a React application, providing a seamless experience for users navigating between these pages.

Nested Routes

Nested routes in React refer to the concept of having child routes within a parent component, where the parent component represents the parent route and child components represent child routes.

Let's consider a scenario where you have a blogging website with several categories of blog posts, such as "Technology", "Travel", and "Food". In this scenario, you want to create a navigation structure where each category has its own page, and each page displays the corresponding blog posts.

Here's an example of how you can implement this scenario using nested routes in React:

import React from "react";
import { Route, Link } from "react-router-dom";

const Technology = () => <h3>Technology Posts</h3>;
const Travel = () => <h3>Travel Posts</h3>;
const Food = () => <h3>Food Posts</h3>;

const Blog = () => {
  return (
    <div>
      <nav>
        <ul>
          <li>
            <Link to="/blog/technology">Technology</Link>
          </li>
          <li>
            <Link to="/blog/travel">Travel</Link>
          </li>
          <li>
            <Link to="/blog/food">Food</Link>
          </li>
        </ul>
      </nav>

      <Route path="/blog/technology" component={Technology} />
      <Route path="/blog/travel" component={Travel} />
      <Route path="/blog/food" component={Food} />
    </div>
  );
};

export default Blog;

In this example, the Blog component represents the parent route, and the Technology, Travel, and Food components represent the child routes. The parent route is defined using the <Route> component, and child routes are defined using nested <Route> components. The Link component is used to navigate between the different routes. When the user clicks on a link, the corresponding child component is displayed within the parent component.

Client Side Routing

Client-side routing refers to the practice of routing web application navigation on the client side as opposed to the server side. In client-side routing, the URL is updated dynamically in response to user actions, such as clicking on a navigation link, without requiring a page refresh. This results in a more seamless user experience and can improve the performance of a web application.

Let's consider a scenario where you are building a single-page e-commerce application. The application has several pages, including a homepage, a product list page, a product detail page, and a shopping cart page.

Here's an example of how you could implement client-side routing in this scenario using React Router:

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

const Home = () => <h3>Home</h3>;
const Products = () => <h3>Product List</h3>;
const ProductDetail = ({ match }) => <h3>Product: {match.params.id}</h3>;
const Cart = () => <h3>Shopping Cart</h3>;

const App = () => (
  <Router>
    <nav>
      <ul>
        <li>
          <Link to="/">Home</Link>
        </li>
        <li>
          <Link to="/products">Products</Link>
        </li>
        <li>
          <Link to="/cart">Cart</Link>
        </li>
      </ul>
    </nav>

    <Route exact path="/" component={Home} />
    <Route exact path="/products" component={Products} />
    <Route path="/products/:id" component={ProductDetail} />
    <Route path="/cart" component={Cart} />
  </Router>
);

export default App;

In this example, we define four components, Home, Products, ProductDetail, and Cart, to represent the different pages in the application. The <Router> component from React Router is used to wrap the entire application, and the <Route> component is used to define each page and map it to a URL. The Link component is used to provide navigation between the different pages, and the match prop is used to extract dynamic URL parameters, such as the product ID in the ProductDetail component. With this setup, when a user clicks on a link, React Router updates the URL and renders the corresponding component, allowing the user to navigate between different pages in the application without a page refresh.

Data writes and HTML forms

React Router emulates HTML Form navigation as the data mutation primitive, according to web development before the JavaScript cambrian explosion. It gives you the UX capabilities of client rendered apps with the simplicity of the "old school" web model.

While unfamiliar to some web developers, HTML forms actually cause a navigation in the browser, just like clicking a link. The only difference is in the request: links can only change the URL while forms can also change the request method (GET vs POST) and the request body (POST form data).

Without client side routing, the browser will serialize the form's data automatically and send it to the server as the request body for POST, and as URLSearchParams for GET. React Router does the same thing, except instead of sending the request to the server, it uses client side routing and sends it to a route action.

let's take a scenario where we have a login form in React Router and the form will redirect to the home page if the login is successful.

  1. Import React and React Router's useHistory hook:
import React, { useState } from 'react';
import { useHistory } from 'react-router-dom';
  1. Create a component for your form:
function LoginForm() {
  const history = useHistory();
  const [formData, setFormData] = useState({
    username: '',
    password: ''
  });

  const handleChange = e => {
    setFormData({
      ...formData,
      [e.target.name]: e.target.value
    });
  };

  const handleSubmit = e => {
    e.preventDefault();

    // Simulate a login request to the server
    setTimeout(() => {
      // If the login is successful, redirect to the home page
      history.push('/home');
    }, 1000);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Username:
        <input
          type="text"
          name="username"
          value={formData.username}
          onChange={handleChange}
        />
      </label>
      <br />
      <label>
        Password:
        <input
          type="password"
          name="password"
          value={formData.password}
          onChange={handleChange}
        />
      </label>
      <br />
      <button type="submit">Login</button>
    </form>
  );
}

export default LoginForm;

In this example, we use the useState hook to manage the form data, the useHistory hook to handle navigation, and the onChange and onSubmit events to handle form input changes and submissions, respectively. When the form is submitted, we simulate a login request to the server by using the setTimeout function. If the login is successful, we use the history.push method to redirect the user to the home page.

More Information

Conclusion

In conclusion, React Router is an essential tool for building complex single-page applications using React. It allows developers to create a routing system that enables them to easily manage the URL structure of their application and navigate between different pages without causing a full page refresh.

By providing a declarative approach to routing, React Router enables developers to define their routing logic in a way that is easy to read and maintain. With its extensive set of features and components, React Router provides developers with a range of options for creating custom routing solutions that fit the specific needs of their application.

While there is a learning curve associated with using React Router, the benefits of this powerful library are well worth the effort. By using React Router, developers can build robust, dynamic, and scalable applications that provide users with a seamless and intuitive browsing experience. With its active community and constant updates, React Router remains an essential tool for any developer working with React.