logo
eng-flag

React Router DOM v6.25.1 Cheatsheet

Table of Contents

  1. Installation
  2. Basic Setup
  3. Route Components
  4. Link and NavLink
  5. URL Parameters
  6. Query Parameters
  7. Nested Routes
  8. Index Routes
  9. Outlet
  10. useNavigate Hook
  11. useLocation Hook
  12. Protected Routes
  13. Lazy Loading
  14. Error Handling
  15. Data Loading with loaders
  16. Actions for Form Submissions
  17. TypeScript Usage
  18. Best Practices

Installation

To install React Router DOM v6.25.1 in your project:

npm install react-router-dom@6.25.1
# or
yarn add react-router-dom@6.25.1

Basic Setup

Set up your app with React Router:

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

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

function App() {
  return <RouterProvider router={router} />;
}

Route Components

Define routes using objects:

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
    children: [
      {
        path: "contacts/:contactId",
        element: <Contact />,
      },
    ],
  },
]);

Create links between routes:

import { Link, NavLink } from 'react-router-dom';

function Navigation() {
  return (
    <nav>
      <Link to="/">Home</Link>
      <NavLink 
        to="/about"
        className={({ isActive, isPending }) =>
          isPending ? "pending" : isActive ? "active" : ""
        }
      >
        About
      </NavLink>
    </nav>
  );
}

URL Parameters

Use dynamic segments in your routes:

const router = createBrowserRouter([
  {
    path: "users/:userId",
    element: <UserProfile />,
  },
]);

function UserProfile() {
  const { userId } = useParams();
  return <div>User ID: {userId}</div>;
}

Query Parameters

Handle query parameters:

import { useSearchParams } from 'react-router-dom';

function SearchResults() {
  const [searchParams, setSearchParams] = useSearchParams();
  const query = searchParams.get('q');

  return (
    <div>
      <h1>Search Results for: {query}</h1>
      <button onClick={() => setSearchParams({ q: 'new query' })}>
        Update Query
      </button>
    </div>
  );
}

Nested Routes

Create nested routes:

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    children: [
      {
        path: "users",
        element: <Users />,
        children: [
          {
            path: ":userId",
            element: <UserProfile />,
          },
          {
            path: "new",
            element: <NewUser />,
          },
        ],
      },
    ],
  },
]);

Index Routes

Define index routes:

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    children: [
      {
        index: true,
        element: <Home />,
      },
      {
        path: "users",
        element: <Users />,
        children: [
          {
            index: true,
            element: <UsersList />,
          },
          {
            path: ":userId",
            element: <UserProfile />,
          },
        ],
      },
    ],
  },
]);

Index routes render in their parent route's outlet at the parent route's path.

Outlet

Render child routes:

import { Outlet } from 'react-router-dom';

function Layout() {
  return (
    <div>
      <h1>My App</h1>
      <nav>{/* navigation items */}</nav>
      <Outlet />
    </div>
  );
}

useNavigate Hook

Navigate programmatically:

import { useNavigate } from 'react-router-dom';

function LoginForm() {
  const navigate = useNavigate();

  const handleSubmit = (event) => {
    event.preventDefault();
    // Perform login logic
    navigate('/dashboard');
  };

  return <form onSubmit={handleSubmit}>{/* form fields */}</form>;
}

useLocation Hook

Access the current location:

import { useLocation } from 'react-router-dom';

function CurrentPath() {
  const location = useLocation();
  return <div>Current path: {location.pathname}</div>;
}

Protected Routes

Implement protected routes:

import { Navigate, useLocation } from 'react-router-dom';

function ProtectedRoute({ children }) {
  const isAuthenticated = checkAuthStatus(); // Implement this function
  const location = useLocation();

  if (!isAuthenticated) {
    return <Navigate to="/login" state={{ from: location }} replace />;
  }

  return children;
}

// In your router configuration
{
  path: "dashboard",
  element: (
    <ProtectedRoute>
      <Dashboard />
    </ProtectedRoute>
  ),
}

Lazy Loading

Implement lazy loading for routes:

import { lazy, Suspense } from 'react';
import { createBrowserRouter } from 'react-router-dom';

const LazyAbout = lazy(() => import('./About'));

const router = createBrowserRouter([
  {
    path: "about",
    element: (
      <Suspense fallback={<div>Loading...</div>}>
        <LazyAbout />
      </Suspense>
    ),
  },
]);

Error Handling

Handle errors with errorElement:

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorBoundary />,
    children: [
      {
        path: "products/:id",
        element: <Product />,
        errorElement: <ProductError />,
      },
    ],
  },
]);

function ErrorBoundary() {
  const error = useRouteError();
  return (
    <div>
      <h1>Oops! Something went wrong.</h1>
      <p>{error.message || 'Unknown error'}</p>
    </div>
  );
}

Data Loading with loaders

Use loaders for data fetching:

const router = createBrowserRouter([
  {
    path: "users/:userId",
    element: <UserProfile />,
    loader: async ({ params }) => {
      return fetch(`/api/users/${params.userId}`).then(res => res.json());
    },
  },
]);

function UserProfile() {
  const user = useLoaderData();
  return <div>{user.name}</div>;
}

Actions for Form Submissions

Handle form submissions with actions:

const router = createBrowserRouter([
  {
    path: "create-user",
    element: <CreateUser />,
    action: async ({ request }) => {
      const formData = await request.formData();
      const userData = Object.fromEntries(formData);
      return createUser(userData);
    },
  },
]);

function CreateUser() {
  const { state } = useNavigation();

  return (
    <Form method="post">
      <input type="text" name="username" />
      <button type="submit" disabled={state === 'submitting'}>
        {state === 'submitting' ? 'Creating...' : 'Create User'}
      </button>
    </Form>
  );
}

Actions are called whenever the app sends a non-get submission ("post", "put", "patch", "delete") to your route.

TypeScript Usage

Use React Router with TypeScript:

import { RouteObject } from 'react-router-dom';

interface UserData {
  id: string;
  name: string;
}

const routes: RouteObject[] = [
  {
    path: "users/:userId",
    element: <UserProfile />,
    loader: async ({ params }): Promise<UserData> => {
      const response = await fetch(`/api/users/${params.userId}`);
      return response.json();
    },
  },
];

Best Practices

  1. Use the new Data APIs (loaders and actions) for data fetching and mutations.
  2. Implement error boundaries for better error handling.
  3. Use lazy loading for better performance in larger apps.
  4. Keep your routes organized and use nested routes when appropriate.
  5. Utilize TypeScript for better type safety and developer experience.
  6. Use the useNavigate hook for programmatic navigation instead of the history object.
  7. Implement proper authentication and authorization checks in your routes.

2024 © All rights reserved - buraxta.com