Encodera

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

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

Оглавление

Параметры маршрута и навигация

У каждой статьи блога должна быть своя страница: /posts/1, /posts/2 и так далее. Писать маршрут для каждой статьи не нужно — достаточно одного маршрута с параметром. Параметр — изменяемая часть пути, которую отмечают двоеточием: /posts/:id.

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

Добавьте маршрут в src/App.jsx:

// src/App.jsx
import PostPage from './pages/PostPage.jsx';
 
// внутри Routes:
<Route path="/posts/:id" element={<PostPage />} />

Этот маршрут подойдёт для /posts/1, /posts/42 и любого другого значения на месте :id.

Чтение параметра

Компонент страницы получает параметры хуком useParams. Создайте src/pages/PostPage.jsx:

// src/pages/PostPage.jsx
import { useParams } from 'react-router';
 
export default function PostPage() {
  const { id } = useParams();
 
  return <h1>Статья № {id}</h1>;
}

Откройте http://localhost:5173/posts/7 — на странице будет «Статья № 7». Значение параметра — всегда строка: '7', а не 7.

Загрузка статьи по параметру

Параметр подставляют в адрес запроса. С хуком useFetch из урока о собственных хуках:

// src/pages/PostPage.jsx
import { useParams } from 'react-router';
import { useFetch } from '../hooks/useFetch.js';
 
export default function PostPage() {
  const { id } = useParams();
  const { data: post, loading, error } = useFetch(
    `https://jsonplaceholder.typicode.com/posts/${id}`,
  );
 
  if (loading) return <p>Загрузка…</p>;
  if (error) return <p>Статья не найдена</p>;
 
  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.body}</p>
    </article>
  );
}

Страница /posts/7 покажет заголовок и текст седьмой статьи. Адрес меняется — меняется id, и useFetch загружает новую статью.

Ссылки на статьи

В списке статей заголовки становятся ссылками. В src/components/PostList.jsx:

// src/components/PostList.jsx
import { Link } from 'react-router';
 
// внутри map:
<li key={post.id}>
  <Link to={`/posts/${post.id}`}>{post.title}</Link>
</li>

Щёлкните по любому заголовку на главной — откроется страница статьи.

Переход из кода

Иногда переходить нужно не по клику на ссылку, а после действия: отправки формы, удаления. Для этого есть хук useNavigate:

// src/pages/PostPage.jsx
import { useNavigate } from 'react-router';
 
const navigate = useNavigate();
 
// в разметке:
<button onClick={() => navigate('/')}>Ко всем статьям</button>
<button onClick={() => navigate(-1)}>Назад</button>

navigate('/') ведёт на главную, navigate(-1) — на предыдущую страницу истории, как кнопка «Назад» в браузере.

Параметры строки запроса

Для фильтров и поиска удобна строка запроса — /?page=2. Её читают хуком useSearchParams: const [searchParams] = useSearchParams(); и searchParams.get('page').

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

Параметр — строка, поэтому строгое сравнение с числом не срабатывает:

const { id } = useParams();
 
// Неправильно: '7' === 7 — это false.
const post = posts.find((item) => item.id === id);
 
// Правильно:
const post = posts.find((item) => item.id === Number(id));

Приводите параметр к числу, когда сравниваете его с числовыми идентификаторами.

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

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