Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Динамические сегменты и параметры

У каждой статьи блога свой адрес: /posts/1, /posts/2 и так далее. Заводить маршрут на каждую статью невозможно, поэтому часть адреса делают динамической. Динамический сегмент начинается с двоеточия, а его значение попадает в объект params.

Маршрут с параметром

Добавьте маршрут в app/routes.ts внутрь макета:

// app/routes.ts
route("posts/:postId", "routes/post.tsx"),

И создайте файл app/routes/post.tsx:

// app/routes/post.tsx
import type { Route } from "./+types/post";
 
export default function Post({ params }: Route.ComponentProps) {
  return <h1>Статья номер {params.postId}</h1>;
}

Откройте http://localhost:5173/posts/7 — появится «Статья номер 7». Тип params.postId — строка, и TypeScript знает о нём благодаря сгенерированным типам: опечатка вроде params.id сразу подсветится.

Ссылка на маршрут

Адрес для ссылки собирают из значения параметра:

// app/routes/home.tsx
import { Link } from "react-router";
 
export default function Home() {
  const ids = [1, 2, 3];
 
  return (
    <ul>
      {ids.map((id) => (
        <li key={id}>
          <Link to={`/posts/${id}`}>Статья {id}</Link>
        </li>
      ))}
    </ul>
  );
}

На главной появятся три ссылки, каждая ведёт на свою страницу статьи.

Несколько параметров

В одном адресе может быть несколько сегментов:

// app/routes.ts
route("authors/:authorId/posts/:postId", "routes/author-post.tsx"),

Для адреса /authors/anna/posts/3 в params будут authorId со значением "anna" и postId со значением "3".

Необязательный сегмент и звёздочка

ЗаписьПодходящие адресаЗначение
:postId/posts/5params.postId
:lang?/about и /en/aboutparams.lang или undefined
*/files/a/b.txtparams["*"], здесь a/b.txt

Маршрут route("*", "routes/not-found.tsx") в конце списка ловит все неизвестные адреса — это страница 404.

Хук useParams

Во вложенном компоненте, которому параметры не переданы пропсами, их читает хук useParams() из react-router. В самом модуле маршрута удобнее пропс params: он точно типизирован.

Частая ошибка

Параметр — всегда строка. Сравнение params.postId === 7 никогда не будет истинным, а поиск статьи по числовому id вернёт пустоту. Превращайте значение в число явно: Number(params.postId), — и проверяйте результат, ведь в адрес можно вписать что угодно, например /posts/abc.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.