Learn how to use React Router to transform your dashboard into a seamless single-page application (SPA) with efficient routing and navigation.
Previously in this course, we built a robust global state management system using Introduction to Context API: Avoiding Prop Drilling in React and Introduction to Custom Hooks: Master Abstraction in React. While our dashboard handles data well, it currently lives on a single page. Today, we’ll move beyond that limitation by implementing react router, the industry-standard library for handling navigation in a Single Page Application (SPA).
In a traditional multi-page website, clicking a link triggers a browser request to the server, which then sends back an entirely new HTML document. This is slow and causes a jarring "flicker" as the page reloads.
In an SPA, the server sends one initial HTML file. When a user clicks a link, the JavaScript (React) intercepts the event, updates the URL, and swaps out the components currently visible on the screen. This makes your dashboard feel snappy and app-like. React Router acts as the "traffic controller," mapping URL paths to specific component trees.
First, install the library in your project:
Bashnpm install react-router-dom
To set up routing, we need to wrap our application in a provider. This provider uses the History API under the hood to track where the user is and where they are going.
In your main.jsx (or index.js), wrap your App component with BrowserRouter:
JSXimport { BrowserRouter } from CE9178">'react-router-dom'; root.render( <BrowserRouter> <App /> </BrowserRouter> );
Now that the router is listening, we define which components should render at which paths. We use the Routes component as a container and individual Route components to define the mapping.
JSXimport { Routes, Route } from CE9178">'react-router-dom'; import Dashboard from CE9178">'./Dashboard'; import Settings from CE9178">'./Settings'; function App() { return ( <Routes> <Route path="/" element={<Dashboard />} /> <Route path="/settings" element={<Settings />} /> </Routes> ); }
When the URL ends in /, the Dashboard component renders. When it ends in /settings, the Settings component replaces it.
Never use standard <a> tags for internal navigation in an SPA. An <a> tag will force a full browser reload, destroying your React state. Instead, use the Link component provided by React Router.
JSXimport { Link } from CE9178">'react-router-dom'; function Navigation() { return ( <nav> <Link to="/">Dashboard</Link> <Link to="/settings">Settings</Link> </nav> ); }
The Link component renders an <a> tag in the DOM, but it prevents the default browser behavior and tells the router to update the view without a refresh.
Profile.jsx to your project.Route to your App.js mapping the path /profile to your Profile component.Link or Routes outside of a BrowserRouter component, your application will throw an error. Ensure the provider is at the very top of your component tree./settings instead of settings/) prevents broken links as your app grows.window.location: Avoid using the browser's native location API to change routes. React Router needs to manage the state internally; bypassing it will break the "back" button functionality.We've successfully installed react-router-dom, wrapped our app in a BrowserRouter, defined a basic set of routes, and implemented navigation using the Link component. By avoiding full-page reloads, we've taken a significant step toward a high-performance dashboard.
Up next: We will learn how to handle dynamic data by implementing URL parameters, allowing us to display specific details for individual items in our dashboard.
Master dynamic routing with React Router. Learn how to define parameterized paths and use the useParams hook to display unique data in your dashboard.
Read moreLearn to manage authentication state in React using the Context API. Build a secure, scalable AuthProvider to track login status and handle user sessions.
Introduction to React Router
Protected Routes for Authenticated Views
Programmatic Navigation
Building the Dashboard Navigation Structure
Asynchronous Data Lifecycle
Caching Strategies with React Query
Mutations and Data Updates
Synchronizing Client and Server State
Integrating Live Data into the Dashboard
Error Handling and Loading UI
Controlled vs Uncontrolled Components
Real-time Form Validation
Schema-based Validation with Zod
Handling Multi-step Forms
Optimizing Form Submissions
Performance Profiling with React DevTools
Refactoring for Scalability
Finalizing Dashboard Data Flow
Deploying the Application
Advanced Hook Composition
Implementing Middleware for State
Advanced Context Patterns
Router Loaders and Data Prefetching
Complex Route Guards
Handling Large Datasets in UI
Testing Hooks and Components
Managing Global Modals
Implementing Keyboard Shortcuts
Optimizing Asset Loading
Internationalization Basics
Managing WebSocket Connections