Routing Magic in React: Building Dynamic Web Applications

Learn what React Router is and the steps for routing in React.

Nirbhay kumar
Bits and Pieces

--

Before you dive into the blog, let me brief you about client and server-side routing.

Client-side routing and server-side routing are two different approaches to handling navigation within web applications. Here’s a brief explanation of the differences:

Client-side routing: In client-side routing, the routing logic is handled on the client side (in the browser). When a user clicks on a link or interacts with the application, the routing is managed by JavaScript running on the client side. This means that the entire application code, including all the necessary views and components, is loaded once when the user first accesses the application. Subsequent navigation and rendering of views are handled by JavaScript manipulating the DOM and updating the URL without making a request to the server. This approach provides a smoother and more interactive user experience as it eliminates page refreshes.

Server-side routing: In server-side routing, the routing logic is handled on the server side. When a user interacts with the application, their request is sent to the server, which determines the appropriate response based on the requested URL. The server renders and returns the HTML content of the requested page. Each time the user navigates to a different page, a new request is made to the server, and the server responds with the corresponding HTML content. This approach results in page refreshes as the entire page is reloaded with each request.

In summary, client-side routing relies on JavaScript to handle navigation and rendering within the browser, providing a more dynamic and responsive user experience. Server-side routing, on the other hand, involves requesting and rendering new pages from the server for each navigation action, resulting in page refreshes but potentially reducing the complexity on the client side. The choice between client-side and server-side routing depends on factors such as the complexity of the application, performance requirements, SEO considerations, and the desired user experience.

Basic Routing

React Router API

React Router is a popular library for handling routing in React applications. It provides a powerful and declarative way to manage the navigation and rendering of different components based on URL paths. React Router helps in building Single Page Applications (SPAs) by enabling client-side routing, where the application can update the UI without causing a full page to reload.

React Router offers a comprehensive API with various components and utilities:

  1. <BrowserRouter>: This component provides the routing functionality for the application using HTML5 history API. It ensures that the URL is updated and keeps the UI in sync with the current URL.
  2. <Route>: The <Route> component is used to define a specific route within the application. It specifies the URL path and the component to be rendered when that route is matched. It can also accept additional props like exact for exact path matching and render for custom rendering logic.
  3. <Switch>: The <Switch> component is used to wrap multiple <Route> components. It ensures that only the first matching route is rendered. This helps prevent multiple routes from being rendered simultaneously.
  4. <Link> and <NavLink>: These components are used to create links for navigation within the application. <Link> provides a simple anchor tag for navigation, while <NavLink> adds additional functionality like highlighting the active link based on the current URL.
  5. URL Parameters: React Router allows you to define dynamic URL parameters in your routes using the :paramName syntax. This allows you to extract values from the URL and pass them as props to the rendered components.
  6. Nested Routes: React Router supports nested routes, allowing you to create a hierarchy of routes within your application. This is useful for building complex UI structures with multiple levels of nested components.
  7. Programmatic Navigation: React Router provides a history object that allows you to programmatically navigate to different routes in response to user actions or other events.

React Router is highly flexible and can be customized to fit the needs of different applications. It supports advanced features like route guarding, route transitions, lazy loading, and more through additional plugins and configuration.

Dont worry, this is just to make you understand of terminologies, hold on….will be explaining you about each of them ✌️✌️ !

There are 3 different packages for React Routing.

  1. react-router: It is the heart of react-router and provides core functionalities for routing in web applications and all the packages for react-router- dom and react-router-native
  2. react-router-native: It is used for routing in mobile applications
  3. react-router-dom: It is used to implement dynamic routing in web applications.

💡 Pro Tip: If you want to reuse React components across all your projects, you could consider using an open-source tool like Bit. Bit lets you extract reusable components from your codebase and share it across multiple projects with a simple bit import your.username/yourComponent command.

Learn more:

How Routing Works / Routing Mechanism

Routing involves navigating between different pages or sections of a website. In the case of client-side rendering with React Router, routing is handled on the client-side rather than relying on the server for each page request.

With client-side rendering, the server is responsible for providing data, while the rendering and routing logic are executed by the client’s web browser. Unlike traditional routing where the server sends separate HTML files for different pages, client-side rendering with React Router relies on a single index.html file.

This approach allows for dynamic routing within a single page application (SPA). The client-side JavaScript takes control of rendering different components based on the URL, providing a seamless user experience. The browser’s history API is utilized to enable smooth navigation, including the ability to go forward and backward through the route history. The URL is also updated dynamically to reflect the current route.

Overall, client-side rendering with React Router offers efficient and responsive routing, enabling a smooth SPA experience with minimal server requests and improved user navigation.

Steps for routing in React:

  1. Installation for react-router-dom:
npm install react-router-dom@6 
or
yarn add react-router-dom@6

2. Check your package.json file for dependencies for confirmation:

{ 
"name" : "reactApp",
"version" : "1.0.0"
"description" : "It is.a react app"
"dependencies" : {
"react" : "^17.0.2",
"react-dom" : "^17.0.2",
"react-icons" : "^4.3.1",
"react-router" : "^6.2.1",
"react-router-dom" : "^6.2.1"
},

3. To enable routing in a React application, you typically start by configuring the BrowserRouter in the index.js file, which serves as the main entry point of the application. This sets up the routing functionality for the entire application.

import {StrictMode } from "react"; 
import {BrowserRouter} from "react-router-dom"
import ReactDOM from "react-router-dom"
import App from "./App"

const root = document.getElementById("root")
ReactDOM.render(
<StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</StrictMode>,
root
);

4. Make different files for routing:

Considering we are making a portfolio website:

About Us Page:

function About() { 
return (
<div>
<h1> This is the about page </h1>
</div>
);
}
export default About;

Home Page:

function Home() { 
return (
<div>
<h1> This is the home page </h1>
</div>
);
}
export default Home;

Contact Page:

function Contact() { 
return (
<div>
<h1> This is the Contact page </h1>
</div>
);
}
export default Home;

5. In the App.js file, which acts as the central component of your application, you define the routes and specify which components should be rendered based on the URL path. This is where you set up the logic for how your application should behave when different routes are accessed.

Within App.js, you import the required components from the react-router-dom library, such as Route, Switch, Link, and BrowserRouter. These components provide the building blocks for configuring and managing routing in your application.

Using the imported components, you define the routes by specifying the URL paths and the corresponding components that should be rendered for each route. This allows you to control the content and functionality of your application based on the user’s navigation.

By structuring and organizing the routes in App.js, you establish the foundation for navigation and content rendering within your application, ensuring that the correct components are displayed based on the current URL path.

import {Routes , Route } from "react-router-dom" 
import Home from "./components/Home/Home"
import Contact from "./components/Contact/Contact"
import About from "./components/About/About"
const App = () => {
return (
<div className="App">
<Routes>
<Route path="/" component={<Home/> } />
<Route path="/about" component={<About/> } />
<Route path="/contact" component={<Contact/> } />
</Routes>
</div>
)}
export default App

This is how we install and set up the basic boilerplate using React Router. After that, it can be extended with its components navigating with respect to website requirements… Hey, you reached more than half, continue reading….

Now let's understand Switch, Link, and NavLink components from the react-router-dom library:

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

// Home component
const Home = () => <h1>Home Page</h1>;

// About component
const About = () => <h1>About Page</h1>;

// Contact component
const Contact = () => <h1>Contact Page</h1>;

// App component
const App = () => {
return (
<Router>
<nav>
<ul>
<li>
<NavLink exact to="/" activeClassName="active">Home</NavLink>
</li>
<li>
<NavLink to="/about" activeClassName="active">About</NavLink>
</li>
<li>
<NavLink to="/contact" activeClassName="active">Contact</NavLink>
</li>
</ul>
</nav>

<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
</Switch>
</Router>
);
};

export default App;

In the above code:

  • The Router component wraps the entire application and provides the routing functionality.
  • The nav element contains the navigation menu with Link or NavLink components for each route.
  • Link and NavLink components are used to create links for navigating between different routes. The exact prop is used for exact path matching, and the activeClassName prop adds a CSS class to the active link.
  • The Switch component ensures that only the first matching Route is rendered.
  • Route components define the paths and the components to be rendered for each route.

With this setup, when a user clicks on a navigation link, the corresponding component will be rendered in the application based on the URL path. For example, accessing “/about” will render the About component.

Here is the overview of all these components:

  1. Routes: Routes refer to the collection of different URL paths defined in a web application. They define the available destinations or pages that users can navigate to. Routes typically map to specific components or views in the application.
  2. Route: A Route component is used to define a specific route within the application. It specifies the URL path and the component to be rendered when that route is matched. Route components are typically used in routing libraries/frameworks like React Router.
  3. Browser Route: A Browser Route is a type of routing mechanism that leverages the browser’s built-in history API. It allows the application to handle navigation and rendering of different components based on the URL path. Browser routing uses JavaScript to manipulate the browser’s history and handle navigation without making requests to the server for every page change.
  4. NavLink: NavLink is a component typically provided by routing libraries like React Router. It is used to create navigation links within the application. NavLink is similar to the HTML anchor tag (<a>) but provides additional functionality specific to routing. It adds an "active" class to the link when it matches the current URL, allowing for visual highlighting of the active route.
  5. Link: Link is another component typically provided by routing libraries like React Router. It is used to create links within the application for navigating between different routes. Link components ensure that the page does not reload entirely when a link is clicked. Instead, they use JavaScript to update the URL and render the appropriate component without making a full page refresh.

FAQs:

Does NavLink redirect to a new page ?

No, the NavLink component does not redirect to a new page in the traditional sense. Instead, it handles navigation within a Single Page Application (SPA) by updating the URL and rendering the appropriate component without causing a full page refresh.

When a NavLink is clicked, it uses JavaScript to update the URL in the browser's address bar based on the specified to prop. This triggers the routing mechanism to match the new URL path with the defined routes and render the corresponding component for that route.

The key difference is that the navigation happens within the same page without a complete reload of the entire HTML document. This is the behavior commonly seen in SPAs, where the application loads once, and subsequent navigation occurs within the same page, resulting in a faster and more seamless user experience.

Of the mentioned above routing techniques, which renders a new page and which not ??

NavLink and Link components are used for in-app navigation and can update the URL without causing a full page reload. The Route component handles rendering within the existing page based on the current URL and route matches, without triggering a new page.

What is the difference between a router and a switch?

The switch works just as the switch statement, by going through each and every route but once it matches the current URL with the route path, it returns back from there rendering that route component specifically. But Router is a standard library under which the switch is a component that helps users to navigate via the implementation of routing in web applications.

Which Router is best for React JS?

BrowserRouter is commonly used for developing small-scale web applications and learning projects. However, it may not be the most suitable option for production-level applications due to its limitations. One drawback is that it is not compatible with legacy servers, resulting in a “Cannot GET Route” error. Additionally, server configuration is required to handle every route defined on the client side, adding complexity and maintenance overhead. Another limitation is that BrowserRouter is primarily designed for Single-Page Applications (SPAs), limiting its functionality to more complex multi-page applications.

For production-level applications, other routing solutions like HashRouter or StaticRouter are often preferred. HashRouter uses the hash portion of the URL to manage routing, making it compatible with legacy servers and eliminating the need for server configuration. StaticRouter is useful for server-side rendering (SSR) applications and handles routing on the server side, providing better compatibility and performance.

It’s important to choose the appropriate routing solution based on the specific requirements and constraints of your project, considering factors such as server compatibility, routing complexity, and scalability.

That's the wrap. Hope you understood routing in React. Web development is the heart of routing!

Connect with me on Twitter or LinkedIn — — — ->

https://www.linkedin.com/in/nirbhay-kumar-a826531ba/

https://twitter.com/Nickky_729

Build Apps with reusable components, just like Lego

Bit’s open-source tool help 250,000+ devs to build apps with components.

Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.

Learn more

Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:

Micro-Frontends

Design System

Code-Sharing and reuse

Monorepo

--

--