Zoom Webinar: Learn and enhance your TypeScript skills | 28th March 2023 | 10 AM PST [10:30 PM IST] Register here
Education

Navigate Your React App Like a Pro: Expert Tips and Tricks for Optimizing React Routing

logo

DhiWise

March 9, 2023
image
Author
logo

DhiWise

{
March 9, 2023
}

Introduction:

React is a popular JavaScript library that provides several features for creating dynamic single-page applications. And one of the most important features of React is React Router, which enables you to handle navigation within your app.

In this blog, we will be sharing ten expert tips and tricks that help you master React routing and optimize your app navigation for a seamless user experience.

Expert Tips and Tricks for Optimizing React Routing

1. Understand the basics of React Router

Before diving into advanced concepts, it is essential to understand the basic components of React Router. The two most important components are-

  1. Router: The Router component is responsible for handling navigation.
  2. Route: The Route component renders the appropriate component based on the URL.

2 .Use nested routes for complex applications

If you are building a complex application with multiple sections, it is a good idea to use nested routes. Nested routes allow you to organize your app into smaller sections and handle navigation more efficiently.

Additionally, it allows better component encapsulation, improves code splitting, gives granular control over routing, and makes code scalable.

3. Use React Router hooks

React Router provides several hooks that allow you to handle navigation and state within your components. The most commonly used hooks are useHistory, useParams, and useLocation. These hooks are essential for building dynamic and responsive user interfaces.

Here are the key benefits of using React Router hooks.
  1. Providing a more concise syntax for handling routing-related functionality.
  2. Improve the performance of your application by reducing the amount of unnecessary rendering by offering selective rendering.
  3. Allow you to handle navigation, route parameters, and other routing-related functionality directly within your components, rather than relying on external routing logic.
  4. Simplify component testing by providing a simpler and more modular approach to handling routing-related functionality.

4. Implement lazy loading

Lazy loading is a technique that allows you to load components only when they are needed, which can improve the performance of your app. React Router provides a built-in method for lazy loading called React.lazy. You can use this method to load components asynchronously, which can speed up the initial load time of your app.

Following is an example of implementing lazy loading in React using the “React.lazy” function and the Suspense component:

Here, we are using React.lazy function to create lazy-loaded components for our HomePage, AboutPage, and ContactPage. Each component is loaded asynchronously only when it's needed.

import React, { lazy, Suspense } from 'react';
import { Route, Switch } from 'react-router-dom';

const HomePage = lazy(() => import('./pages/HomePage'));
const AboutPage = lazy(() => import('./pages/AboutPage'));
const ContactPage = lazy(() => import('./pages/ContactPage'));

function App() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <Switch>
          <Route exact path="/" component={HomePage} />
          <Route exact path="/about" component={AboutPage} />
          <Route exact path="/contact" component={ContactPage} />
        </Switch>
      </Suspense>
    </div>
  );
}

The “Suspense” component is to specify a fallback UI to display while the lazy-loaded components are being loaded. In this case, we're simply displaying the text "Loading...".

Finally, we're using the “Route” and “Switch” components from react-router-dom to define our routes and specify which component to render for each route. The “exact” prop is used to ensure that the component is only rendered for an exact match of the route path.

5. Implement error handling

Error handling is an important aspect of any application. When it comes to React routing, it is essential to handle errors related to routing. For example, if a user enters an incorrect URL, you should handle that error and redirect them to the appropriate page.

The key benefits of implementing error handling:
  1. Improves user experience by preventing the app from displaying unexpected crashes and error messages. Instead, it helps to handle errors in a user-friendly way. 
  2. Improves debugging with detailed error messages, so developers can fix bugs easily.
  3. Enables developers to create more stable and robust code that is less likely to crash.
  4. Prevents data loss by catching errors before they cause data to be overwritten or lost.
  5. Helps to prevent security vulnerabilities by catching errors that could potentially cause security issues.
  6. Error handling helps to make code maintainable.

6. Use Route guards

Route guards are functions that are executed before rendering a Route component. They are useful for checking if a user is authorized to access a particular route or if certain conditions are met. 

Simple implementation of a Route guard:
// Define your guard function

function isAuthenticated(route, params) {
  // Check if user is authenticated
  const isAuthenticated = /* your authentication logic here */;
  
  if (!isAuthenticated) {
    // Redirect to login page or unauthorized page
    window.location.href = '/login';
    return false;
  }
  
  return true;
}

Once you define your Route guard apply your guard function to Route.

// Apply guard function to Route

window.onhashchange = function() {
  const route = window.location.hash.substring(1);
  const params = /* any necessary parameters */;
  
  // Apply your guard function to the route

  const isAllowed = isAuthenticated(route, params);
  if (!isAllowed) {
    // Cancel navigation
    window.history.back();
  }
};

7. Use dynamic route matching

Dynamic route matching is a technique that allows you to match URLs with different parameters. For example, if you have a blog with multiple posts, you can use dynamic route matching to match each post with its own URL. React Router provides a built-in method for dynamic route matching called “path-to-regexp”.

Example of dynamic route matching:
const pathToRegexp = require('path-to-regexp');

// Define the route pattern with a parameter placeholder
const pattern = '/users/:id';

// Convert the route pattern to a regular expression
const regex = pathToRegexp(pattern);

// Test a URL to see if it matches the route pattern
const url = '/users/123';
const match = regex.exec(url);

if (match) {
  // Extract the parameter value from the URL using the parameter key
  const key = 'id';
  const value = match[1]; // The first match group corresponds to the parameter value

  console.log(`Matched route "${pattern}" with param "${key}": ${value}`);
} 
else 
{
  console.log(`No match for route "${pattern}"`);
}

8. Use query parameters

Query parameters are a way to pass data between pages using the URL. They are useful for filtering data or passing user input to the next page. React Router provides a built-in method for query parameters called “useLocation”.

The following steps demonstrate how to pass data in React.js using query parameters with the useLocation hook:

1. Import the “useLocation” hook from the react-router-dom package:

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

2. use the “useLocation” hook to get access to the query string parameters in the URL.

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

function UserDetails() {
  const location = useLocation();
  const searchParams = new URLSearchParams(location.search);
  const userId = searchParams.get('id');
  
  // Fetch the user data using the userId
  // ...
  
  return (
    <div>
      <h1>User Details</h1>
      <p>User ID: {userId}</p>
      {/* Display the user details */}
    </div>
  );
}

9. Use URL generation

URL generation is a technique that allows you to generate URLs dynamically. This is useful for creating links to different parts of your app or sharing URLs with other users. React Router provides a built-in method for URL generation called “Link”.

In the example discussed in the use query parameter section, we need to use the  “userId” to fetch the user data from an API or a local data source. Finally, we can render the user details in the component.

And to pass the “id” parameter from the list of users component to the user details component, we can use the “Link” component from react-router-dom with the “to” prop that includes the query parameter:

import { Link } from 'react-router-dom';

function UserList() {
  const users = [ /* array of user objects */ ];
  
  return (
    <div>
      <h1>User List</h1>
      <ul>
        {users.map(user => (
          <li key={user.id}>
            <Link to={`/user-details?id=${user.id}`}>{user.name}</Link>
          </li>
        ))}
      </ul>
    </div>
  );
}

In this example, we use the “Link” component to create a link to the user details page (/user-details) with the “id” query parameter set to the ID of the current user (user.id). When the user clicks on the link, they will be taken to the user details page and the “useLocation” hook will extract the “id” parameter from the URL.

10. Use layout component

Layout component is a wrapper component that can be used to add common elements to multiple pages. For example, if you have a header and footer that appear on every page, you can use a layout component to wrap each page and add the header and footer. This can make your code more modular and easier to maintain.

Here's how we can create the layout component:

import React from 'react';
const Layout = ({ children }) => {
  return (
    <div>
      <header>
        <h1>My Website</h1>
      </header>
      <main>{children}</main>
      <footer>
        <p>© 2023 My Website</p>
      </footer>
    </div>
  );
};

export default Layout;

Here, we have a functional component named “Layout” that takes in a “children” prop. The “children” prop is a special prop in React that allows us to pass in other components that will be rendered inside our “Layout” component.

In this component, we have a <header> section that contains the website title, a <main> section where our other components will be rendered, and a <footer> section that contains the copyright notice.

Now, let's say we have a “HomePage” component that we want to render inside our “Layout” component. Here's how we can do it:

import React from 'react';
import Layout from './Layout';

const HomePage = () => {
  return (
    <div>
      <h2>Welcome to my website!</h2>
      <p>Here's some content for the home page...</p>
    </div>
  );
};

const App = () => {
  return (
    <Layout>
      <HomePage />
    </Layout>
  );
};

export default App;

Here, we import our “Layout” component and create a “HomePage” component that contains some content for the home page. Then, we wrap our “HomePage” component inside our “Layout” component by passing it as a child to the “Layout” component.

When we run our “App” component, we'll see that the “HomePage” component is rendered inside our “Layout” component, with the header and footer sections appearing on every page of our website.

Conclusion:

Mastering React routing is essential for building successful single-page web applications. By following these ten expert tips and tricks, you can optimize your app navigation and provide a seamless user experience. 

Understanding the basic components of React Router, using nested routes, implementing React Router hooks, lazy loading, error handling, route guards, dynamic route matching, query parameters, URL generation, and layout components are all essential for building a successful app. 

So, follow these expert tips and master React routing like a pro.

Besides that, if you are looking for the best app development platform that can speed up your React web app development try DhiWise React Builder and build a web app in just a few steps without affecting the code quality.

Sign up now to explore more about DhiWise and its features.