Skip to content
Learni
View all tutorials
Frontend

How to Master React Router v6.4+ in 2026

18 minINTERMEDIATE
Lire en français

Introduction

React Router v6.4 introduced a new paradigm based on data routers that simplifies data loading and form management. This tutorial guides you step by step through building a robust SPA with nested routes, loaders, and actions. You will learn to manage navigation state, protect routes, and optimize performance. Every concept is illustrated with production-ready TypeScript code.

Prerequisites

  • Node.js 18+
  • React 18+ and TypeScript
  • Basic knowledge of React and hooks
  • npm or yarn installed

Installation and Configuration

terminal
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install react-router-dom@latest

This command creates a Vite project with TypeScript and installs the latest version of React Router. Vite provides a fast and modern development environment.

Create the Main Router

src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import Root from './routes/Root';
import Home from './routes/Home';

const router = createBrowserRouter([
  {
    path: '/',
    element: <Root />,
    children: [
      { index: true, element: <Home /> }
    ]
  }
]);

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

We use createBrowserRouter to define the route structure. RouterProvider replaces BrowserRouter and enables data loading features.

Nested Routes and Outlet

src/routes/Root.tsx
import { Outlet, Link } from 'react-router-dom';

export default function Root() {
  return (
    <div>
      <nav>
        <Link to="/">Accueil</Link>
        <Link to="/dashboard">Dashboard</Link>
      </nav>
      <main>
        <Outlet />
      </main>
    </div>
  );
}

Outlet renders child routes. Link components enable client-side navigation without page reloads.

Loader for Data Fetching

src/routes/Dashboard.tsx
import { useLoaderData } from 'react-router-dom';

export async function loader() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts');
  return res.json();
}

export default function Dashboard() {
  const posts = useLoaderData() as any[];
  return (
    <div>
      <h1>Posts</h1>
      <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>
    </div>
  );
}

The loader runs before the component renders. useLoaderData retrieves the data synchronously inside the component.

Action and Form Handling

src/routes/NewPost.tsx
import { Form, redirect } from 'react-router-dom';

export async function action({ request }: { request: Request }) {
  const formData = await request.formData();
  await fetch('https://jsonplaceholder.typicode.com/posts', {
    method: 'POST',
    body: formData
  });
  return redirect('/dashboard');
}

export default function NewPost() {
  return (
    <Form method="post">
      <input name="title" required />
      <button type="submit">Créer</button>
    </Form>
  );
}

Actions intercept form submissions. redirect allows navigation after a successful mutation.

Protected Route with Loader

src/routes/Protected.tsx
import { redirect, LoaderFunctionArgs } from 'react-router-dom';

export async function protectedLoader({ request }: LoaderFunctionArgs) {
  const isLoggedIn = localStorage.getItem('token');
  if (!isLoggedIn) {
    return redirect('/login?redirectTo=' + new URL(request.url).pathname);
  }
  return null;
}

A loader can redirect the user before rendering. This effectively protects sensitive routes.

Best Practices

  • Always type the data returned by loaders
  • Use errorElement to handle loading errors
  • Prefer data-based routes over useEffect
  • Separate loaders and actions into dedicated files
  • Test redirects with integration tests

Common Mistakes to Avoid

  • Forgetting to import and use RouterProvider
  • Calling React Router hooks outside of a router
  • Not handling async errors in loaders
  • Using incorrect relative paths in nested links

Further Learning

Discover our advanced courses on React and the modern ecosystem: https://learni-group.com/formations