How to Implement MemoryRouter in React

This article provides a straightforward guide on how to implement and use MemoryRouter in a React application. You will learn what MemoryRouter is, why you should use it instead of BrowserRouter in certain scenarios, and how to configure it for both functional components and unit testing environments.

What is MemoryRouter?

MemoryRouter is a router component provided by the react-router-dom library. Unlike BrowserRouter, which interacts with the browser’s history API and updates the URL address bar, MemoryRouter keeps the history of your URL in system memory.

Because it does not rely on a browser’s URL bar, it is the ideal choice for: * Testing: Simulating navigation and routing behavior in Jest or Vitest environments. * Non-browser environments: Building applications for platforms like React Native or Electron where a standard browser address bar does not exist. * Embedded Widgets: Creating a micro-frontend or a widget embedded on a third-party website where you do not want to interfere with the host website’s URL.

Basic Implementation

To implement MemoryRouter, you must first import it along with your standard routing components from react-router-dom.

Here is a step-by-step implementation:

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

const Home = () => <h2>Home Screen</h2>;
const Profile = () => <h2>Profile Screen</h2>;

function App() {
  return (
    <MemoryRouter initialEntries={['/']} initialIndex={0}>
      <nav>
        <Link to="/">Home</Link> | <Link to="/profile">Profile</Link>
      </nav>

      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/profile" element={<Profile />} />
      </Routes>
    </MemoryRouter>
  );
}

export default App;

In this setup, clicking the links will transition the components on the screen, but the URL in your browser’s address bar will remain unchanged.

Configuring MemoryRouter Props

MemoryRouter accepts two specific props that allow you to control the simulation of the navigation history:

Implementing MemoryRouter for Testing

The most common real-world use case for MemoryRouter is inside unit tests. When testing a component that uses React Router hooks (like useNavigate, useParams, or useLocation), the component will crash unless it is wrapped in a router provider. MemoryRouter allows you to test these components in isolation.

Here is an example of testing a component using React Testing Library and MemoryRouter:

import { render, screen } from '@testing-library/react';
import { MemoryRouter, Routes, Route } from 'react-router-dom';
import UserProfile from './UserProfile'; // Component that reads user ID from URL

test('renders user profile based on route parameter', () => {
  render(
    <MemoryRouter initialEntries={['/users/42']}>
      <Routes>
        <Route path="/users/:id" element={<UserProfile />} />
      </Routes>
    </MemoryRouter>
  );

  // Assert that the component successfully read the ID "42" from the route
  expect(screen.getByText(/User ID: 42/i)).toBeInTheDocument();
});

By wrapping the component under test inside a MemoryRouter with initialEntries, you can mock any specific URL state to test different conditional rendering paths.