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:
initialEntries: An array of URLs that represent the history stack. For example,initialEntries={['/home', '/profile', '/settings']}sets up a history of three pages.initialIndex: An integer pointing to the index of theinitialEntriesarray that the router should start on. If you passinitialIndex={1}, the application will boot directly into the/profileroute.
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.