DEV Community

loading...

Choosing a Router in React Apps

akashshyam profile image Akash Shyam ・3 min read

Hey guys 👋, I hope you're having a great day. I'm going to be talking about the various advantages and disadvantages of routers in react-router and how to pick one.

There are three types of routers that are given by react-router. We'll go through each of them in detail later:

1. Browser Router
Uses everything after the TLD(.com, .in, .co etc) or port as the path. In localhost:3000/xyz, /xyz is the path.

2. Hash Router
Uses everything after the # as the path. In localhost:3000/#/xyz, /xyz is the path.

3. Memory Router
Does not use the URL to track navigation, it's a completely different ballgame.

Let's move on to looking at the various routers in detail.

Hash Router

Now that we understand the basics of a hash router, let's look at some code.

import { HashRouter, Route } from 'react-router-dom';

function App() {
    return (
        <HashRouter>
            <Route path="/" exact component={page1} />
            <Route path="/page2" component={page2} />
        </HashRouter>
    );
}
Enter fullscreen mode Exit fullscreen mode

We have an App() component in which we are returning a HashRouter with some routes. I have 2 components page1 and page2 that return an h1. If you run our little app in the browser, you will find out that react router automatically adds a # before the path.

Screenshot 2021-03-11 at 17.01.11

That's pretty much it. This is the main visual difference between a browser router and a hash router. I know this seems like its not very relevant adding the #, but there is a valid reason for this.

Memory Router

I've kinda skipped around how memory routers work behind the scenes. A react router keeps a history of the URL but does not update the address bar. Let's look at an example

I'm using the same App() component as above with 1 tiny change.

import { MemoryRouter, Route } from 'react-router-dom';

function App() {
    return (
        <MemoryRouter>
            <Route path="/" exact component={page1} />
            <Route path="/page2" component={page2} />
        </MemoryRouter>
    );
}
Enter fullscreen mode Exit fullscreen mode

Also, I'm adding a Link component to my page1 and page2 components.

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

function page1() {
    return (
        <div>
            <div>Page 1</div>
            <Link to="/">Go to Page 2</Link>
        </div>
    );
}

function page2() {
    return (
        <div>
            <div>Page 2</div>
            <Link to="/page2">Go to Page 1</Link>
        </div>
    );
}
Enter fullscreen mode Exit fullscreen mode

If you run the app, you will find that the components which are rendered are different and the links work however the URL does not change.

Comparing

The browser router is often very complicated to deploy. A lot of hosting providers assume that we use this kind of routing and simplify the process. Let me explain why that is:

A traditional server
Screenshot 2021-03-11 at 18.09.53

A traditional server does not understand the /page1. However, a normal deployment server will reach out to our server and it will return a 404 error since the /page1 is gibberish to it.

You might think, "How does our create-react-app dev server work?". The create-react-app dev server will first check to see if there are any development resources(js file, css file etc) with /page1. Then, it will check the public folder. If none of these were fulfilled, then it will serve the index.html file(linked to our JSX, routers etc). Our routes will then pick this up and give content accordingly(routing is client side).

Enough of browser routers, let's talk hash routers. We can quite easily configure our server to ignore the # and server the entire html file regardless of the route. This hash will be used by our routes to show the appropriate content.

Memory routers change the address bar. This probably will leave the user hanging and he or she might think that his computer has hanged or there is an issue with the site. This is bad user experience.

The router you pick largely depends on the application, amount of resources and deployment. Use browser routers if your hosting provider automatically does most of the config for you or you have the resources to hire a devOps guy. I'd recommend hash routers when you want to quickly deploy without any hassle. Memory routers are helpful in test environments and react native. I added memory router just for your information but I'm not a huge fan of it.

That's all for now, I hope you guys liked this post. Like this post and follow me! Bye 👋

Discussion (2)

pic
Editor guide
Collapse
amn3s1a2018 profile image
Amn3s1a2018

Nice summary, but what about Next.js or Gatsby?

Collapse
akashshyam profile image
Akash Shyam Author

Thank you, I think that it will be the same across next.js and gatsby. Actually, what I've mentioned in the post is the same across all SPAs