How do you pick a router in React JS?

Samanja Cartagena
4 min readNov 19, 2022

You can pick a router according to your needs

Many routers are available depending on the environment you are running in. The recommended router for all react projects is createBrowserRouter. It uses the DOM API to update and manage the history stack. Of course, you have to npm install ‘react-dom’ and npm install ‘react-router-dom’ first.

CreateBrowserRouter

import * as React from "react";
import * as ReactDOM from "react-dom";
import {
createBrowserRouter,
RouterProvider,
} from "react-router-dom";

import Root, { rootLoader } from "./routes/root";
import Team, { teamLoader } from "./routes/team";

const router = createBrowserRouter([
{
path: "/",
element: <Root />,
loader: rootLoader,
children: [
{
path: "team",
element: <Team />,
loader: teamLoader,
},
],
},
]);

ReactDOM.createRoot(document.getElementById("root")).render(
<RouterProvider router={router} />
);
import * as React from "react";
import * as ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";

ReactDOM.render(
<BrowserRouter>
{/* The rest of your app goes here */}
</BrowserRouter>,
root
);

Even though using hash is not recommended, the createHashRouter can be useful if you want to configure your web server in order to direct all traffic to your react router application. Instead of having normal URLs, it will be the hash portion of the URL to manage all applications. Although, functionally it will do the same thing as a createBrowserRouter. A hashrouter can be used when you do not want to send the url to the server for some reason. It should not be used unless and until you absolutely have to.

CreateHashRouter

import * as React from "react";
import * as ReactDOM from "react-dom";
import {
createHashRouter,
RouterProvider,
} from "react-router-dom";

import Root, { rootLoader } from "./routes/root";
import Team, { teamLoader } from "./routes/team";

const router = createHashRouter([
{
path: "/",
element: <Root />,
loader: rootLoader,
children: [
{
path: "team",
element: <Team />,
loader: teamLoader,
},
],
},
]);

ReactDOM.createRoot(document.getElementById("root")).render(
<RouterProvider router={router} />
);
import * as React from "react";
import * as ReactDOM from "react-dom";
import { HashRouter } from "react-router-dom";

ReactDOM.render(
<HashRouter>
{/* The rest of your app goes here */}
</HashRouter>,
root
);

If you are interested in managing history stack, you can use createMemoryRouter. Instead of using the browser’s history a memory router manages its own history stack. It can be very handy for non browser environments such as react-native and especially when we do not want the history stack of the browser to interfere with what we are doing such as testing.

import {
RouterProvider,
createMemoryRouter,
} from "react-router-dom";
import * as React from "react";
import {
render,
waitFor,
screen,
} from "@testing-library/react";
import "@testing-library/jest-dom";
import CalendarEvent from "./routes/event";

test("event route", async () => {
const FAKE_EVENT = { name: "test event" };
const routes = [
{
path: "/events/:id",
element: <CalendarEvent />,
loader: () => FAKE_EVENT,
},
];

const router = createMemoryRouter(routes, {
initialEntries: ["/", "/events/123"],
initialIndex: 1,
});

render(<RouterProvider router={router} />);

await waitFor(() => screen.getByRole("heading"));
expect(screen.getByRole("heading")).toHaveTextContent(
FAKE_EVENT.name
);
});

Internally <MemoryRouter> stores its locations in an array. It isn’t tied to the history stack of the browser. This can be ideal if you want complete control over the history stack like testing.

import * as React from "react";
import { create } from "react-test-renderer";
import {
MemoryRouter,
Routes,
Route,
} from "react-router-dom";

describe("My app", () => {
it("renders correctly", () => {
let renderer = create(
<MemoryRouter initialEntries={["/users/mjackson"]}>
<Routes>
<Route path="users" element={<Users />}>
<Route path=":id" element={<UserProfile />} />
</Route>
</Routes>
</MemoryRouter>
);

expect(renderer.toJSON()).toMatchSnapshot();
});
});

What is a router provider?

All router objects are passed to this component to render your app and enable the rest of the APIs.

import {
createBrowserRouter,
RouterProvider,
} from "react-router-dom";

const router = createBrowserRouter([
{
path: "/",
element: <Root />,
children: [
{
path: "dashboard",
element: <Dashboard />,
},
{
path: "about",
element: <About />,
},
],
},
]);

ReactDOM.createRoot(document.getElementById("root")).render(
<RouterProvider
router={router}
fallbackElement={<BigSpinner />}
/>
);

The fallback element is a BigSpinner component in this case. But it can be a page with a message too. It can be any component that you build and will be rendered when the router is not working.

Altogether, you have a wide array of options to choose from and can chose your router intelligently and can really do interesting things while routing.

You are free!!

Spread the love like a spread operator

…Love

Samanja

--

--