Frontend
Intermediate
Josué Hernández

Josué Hernández

    Understanding Nested Routes in React
    What Are Nested Routes?
    How to Implement Nested Routes in React Router?
    1. Setting Up the Main Router Configuration
    2. Creating the Dashboard Component
    3. Creating Child Components
    How Nested Routes Work in the Browser
    Optimizing Performance with Lazy Loading
    What Is Lazy Loading?
    How to Implement Lazy Loading in React Router?
    1. Update the Router Configuration with Lazy Loading
    2. How Lazy Loading Improves Performance
    Fallback UI for Better UX
    Best Practices for Nested Routes & Lazy Loading
    Conclusion
    Additional Resources

In React applications, handling complex navigation efficiently is crucial for scalability, performance, and maintainability. Two essential techniques to achieve this are Nested Routes and Lazy Loading. These approaches help structure routes logically and improve load times by deferring unnecessary component loading.

In this blog, we'll explore how Nested Routes and Lazy Loading work, their benefits, and how to implement them in a React Router project.


Understanding Nested Routes in React

What Are Nested Routes?

Nested Routes allow child routes to be rendered inside a parent route, maintaining a structured navigation system. This is useful when dealing with dashboards, multi-step forms, user profiles, and settings pages, where child views depend on a parent context.

For example, instead of defining separate routes like:

PLAIN TEXT
/dashboard
/overview
/settings

We can structure them as:

PLAIN TEXT
/dashboard (Parent Route)
/dashboard/overview (Child Route)
/dashboard/settings (Child Route)

This makes navigation more organized and intuitive.

How to Implement Nested Routes in React Router?

1. Setting Up the Main Router Configuration

We use React Router's Outlet component to render child components dynamically inside a parent layout.

TYPESCRIPT
import { BrowserRouter as Router, Routes, Route, Link, Outlet } from "react-router-dom";
import Dashboard from "./Dashboard";
import Overview from "./Overview";
import Settings from "./Settings";

function App() {
  return (
    <Router>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/dashboard">Dashboard</Link>
      </nav>

      <Routes>
        <Route path="/" element={<h2>Welcome to the App</h2>} />
        <Route path="/dashboard" element={<Dashboard />}>
          <Route path="overview" element={<Overview />} />
          <Route path="settings" element={<Settings />} />
        </Route>
      </Routes>
    </Router>
  );
}

export default App;

2. Creating the Dashboard Component

The Dashboard component acts as a wrapper for nested routes and contains a navigation system to navigate between Overview and Settings.

TYPESCRIPT
import { Link, Outlet } from "react-router-dom";

const Dashboard = () => {
  return (
    <div>
      <h2>Dashboard</h2>
      <nav>
        <Link to="overview">Overview</Link>
        <Link to="settings">Settings</Link>
      </nav>

      {/* Renders the child route component dynamically */}
      <Outlet />
    </div>
  );
};

export default Dashboard;

3. Creating Child Components

Each child route will display specific content inside the Dashboard layout.

Overview Component:

TYPESCRIPT
const Overview = () => <h3>Dashboard Overview</h3>;
export default Overview;

Settings Component:

TYPESCRIPT
const Settings = () => <h3>Account Settings</h3>;
export default Settings;

How Nested Routes Work in the Browser

  1. Visiting /dashboard renders the Dashboard component.
  2. Clicking "Overview" updates the URL to /dashboard/overview, rendering the Overview component inside Dashboard.
  3. Clicking "Settings" updates the URL to /dashboard/settings, replacing the Overview component with Settings.

Optimizing Performance with Lazy Loading

What Is Lazy Loading?

Lazy Loading (or Code Splitting) delays the loading of components until they are needed, reducing the initial JavaScript bundle size and improving performance.

Instead of loading everything upfront, we can dynamically import components only when a user navigates to them.

How to Implement Lazy Loading in React Router?

React provides React.lazy() to defer component loading. We wrap it in Suspense to show a fallback UI while loading.

1. Update the Router Configuration with Lazy Loading

TYPESCRIPT
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import { lazy, Suspense } from "react";
import Dashboard from "./Dashboard";

const Overview = lazy(() => import("./Overview"));
const Settings = lazy(() => import("./Settings"));

function App() {
  return (
    <Router>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/dashboard">Dashboard</Link>
      </nav>

      <Routes>
        <Route path="/" element={<h2>Welcome to the App</h2>} />
        <Route path="/dashboard" element={<Dashboard />}>
          <Route
            path="overview"
            element={
              <Suspense fallback={<p>Loading Overview...</p>}>
                <Overview />
              </Suspense>
            }
          />
          <Route
            path="settings"
            element={
              <Suspense fallback={<p>Loading Settings...</p>}>
                <Settings />
              </Suspense>
            }
          />
        </Route>
      </Routes>
    </Router>
  );
}

export default App;

2. How Lazy Loading Improves Performance

Initial Load Optimization: The app loads only essential components.

On-Demand Loading: Additional components load only when needed.

Faster Page Load Time: Improves first meaningful paint (FMP) and time to interactive (TTI).

Efficient for Large Applications: Reduces unused JavaScript, keeping the app responsive.

Fallback UI for Better UX

The Suspense component allows us to display a loading message or spinner while fetching lazy-loaded components:

TYPESCRIPT
<Suspense fallback={<p>Loading...</p>}>
  <Overview />
</Suspense>

Best Practices for Nested Routes & Lazy Loading

🔥 Use Nested Routes for Modular Design: Helps maintain cleaner, structured navigation.

🔥 Keep Routes Readable: Avoid deep nesting beyond two or three levels.

🔥 Leverage Lazy Loading Smartly: Load large components dynamically to improve performance.

🔥 Use a Meaningful Fallback UI: A spinner or skeleton loader enhances user experience.

🔥 Avoid Overusing Lazy Loading: Too many lazy-loaded components may increase latency.


Conclusion

By combining Nested Routes and Lazy Loading, we can build scalable React applications with an optimized structure and better performance. Nested Routing helps organize navigation, while Lazy Loading ensures only required components load when needed, boosting speed and efficiency.

This is just the beginning! Future blogs will explore protected routes, authentication-based navigation, and performance optimization techniques. 🚀


Additional Resources

🔗 React Router Documentation

🔗 Code Splitting in React


Josué Hernández
Josué Hernández

Last Update on 2025-03-11

Related Blogs

© 2024 Effort Stack. All rights reserved