DEV Community

Armstrong Olusoji
Armstrong Olusoji

Posted on

How Next router handles routing differently from React Router Dom

React and Next.js are similar in some ways, and different in others. One of those differences is in how both frameworks handle routing. As someone who has used React for most of my career, I was surprised to find how different Next.js routing is from React Routing. Understanding these differences is crucial for developers working with either framework. I will continue to update this article as I learn more about Next routing. But for now, this article will cover the following:

  • Declarative vs file-based routing
  • Dynamic routing

Before we dive in, it's important to note that routing in React is typically done with React Router Dom, an external library. Next.js, however, has its inbuilt routing capabilities.

Also, this article is written for the HNG internship. It is a three-month-long program where new developers can test themselves. They also offer career services such as recruitment and mentorship. More details here

Okay, let's explore these differences in detail.

Declarative vs File-Based Routing

The first major difference between routing in React and Next.js is how routing is handled.

React Routing

In React, we need to:

  1. Add BrowserRouter to index.js
  2. Declare the Routes component
  3. Nest each Route component inside Routes
  4. Add the intended component we want to route to, and the URL to each Route component

Here's an example:

// index.js
ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById('root')
);

// App.js
const App = () => {
  return (
    <div>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/blog" element={<Blog />} />
        <Route path="/blog/:id" element={<BlogPost />} />
      </Routes>
    </div>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

In summary, you have to define each route in React explicitly.

Next.js Routing

Next.js uses a different paradigm. You don't have to define routes explicitly due to Next's file-based routing, which uses the path of the file where your component is located as the URL of that route.

Using the same example as we used for React, our routes in Next.js might look like this:

my-next-app/
├── pages/
│   ├── index.js       // Corresponds to "/"
│   ├── about.js       // Corresponds to "/about"
│   ├── blog/
│   │   ├── index.js   // Corresponds to "/blog"
│   │   └── [id].js    // Corresponds to "/blog/[id]"
├── components/
│   ├── Home.js        // Component used in pages/index.js
│   ├── About.js       // Component used in pages/about.js
│   ├── Blog.js        // Component used in pages/blog/index.js
│   ├── BlogPost.js    // Component used in pages/blog/[id].js
└── public/
    └── ...
Enter fullscreen mode Exit fullscreen mode

Next.js chose this file-based routing approach to simplify the routing process and make it more intuitive. It eliminates the need for a separate routing configuration, reducing boilerplate code and making the project structure more straightforward. This approach aligns well with Next.js's goal of providing a more opinionated and streamlined development experience.

In Next.js, we write our JSX inside About.js and then render it inside its route, about.js. This introduces an important design pattern when using Next.js - separating concerns:

// pages/about.js
import About from '../components/About';

export default function AboutPage() {
  return <About />;
}

// components/About.js
import React from 'react';

const About = () => {
  return <h1>About Page</h1>;
};

export default About;
Enter fullscreen mode Exit fullscreen mode

In summary, Next.js routes are defined based on the component tree and the respective paths.

Dynamic Routing

The declarative approach of React Router and the file-based approach of Next.js impact how dynamic routes are built and executed in both frameworks.

Dynamic Routing in React

In React, you can define a dynamic route by adding a colon to the route URL:

// App.js
const App = () => {
  return (
    <div>
      <Routes>
        <Route path="/blog" element={<Blog />} />
        <Route path="/blog/:id" element={<BlogPost />} />
      </Routes>
    </div>
  );
};
export default App;
Enter fullscreen mode Exit fullscreen mode

Each blog has a unique URL, so the path is /blog/whatever-the-title-of-the-blog-is.

Here's how you would use the dynamic parameter in React:

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

const BlogPost = () => {
  const { id } = useParams();

  return (
    <div>
      <h1>Blog Post {id}</h1>
      {/* Use the id to fetch and display the blog post */}
    </div>
  );
};

export default BlogPost;
Enter fullscreen mode Exit fullscreen mode

Dynamic Routing in Next.js

Next.js handles dynamic routing differently:

├── pages/
│   ├── blog/          // Corresponds to "/blog" 
│   │   └── [id].js    // Corresponds to "/blog/[id]"
Enter fullscreen mode Exit fullscreen mode

Next.js indicates that a route should be dynamic by putting a variable inside square brackets. Here's how we might configure this:

import { useRouter } from 'next/router';

const BlogPost = () => {
  const router = useRouter(); // Get the router object
  const { id } = router.query; // Destructure to get the 'id' from the URL

  return (
    <div>
      <h1>Blog Post {id}</h1>
      {/* Use the id to fetch and display the blog post */}
    </div>
  );
};

export default BlogPost;
Enter fullscreen mode Exit fullscreen mode

Here's what Next.js is doing under the hood:

  1. Inside the [id].js file, we call the useRouter() method. This method reads [id].js file and saves it as an object. We save the result inside the router variable.
  2. Then, we use the query function from useRouter to extract a specific part of the object that was generated. In this case, we collect the id.
  3. Next.js will use that id collected as the URL for that route.

Let's see how we would link to this route:

import Link from 'next/link';

const BlogList = ({ blogs }) => {
  return (
    <div>
      <h1>Blog List</h1>
      <ul>
        {blogs.map((blog) => (
          <li key={blog.id}>
            <Link href={`/blog/${blog.id}`}>
              <a>{blog.title}</a>
            </Link>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default BlogList;
Enter fullscreen mode Exit fullscreen mode

We're taking the URL /blog/[id].js, and replacing it with /blog/${blog.id}. This way, whatever value blog.id holds becomes the URL, giving each individual blog its own unique route.

Conclusion

While both React (with React Router) and Next.js provide powerful routing capabilities, they approach it differently. React Router uses a more declarative style, while Next.js leverages file-based routing. Understanding these differences can help developers choose the right framework for their needs and use routing effectively in their applications.

Top comments (0)