Параметры маршрута и навигация
У каждой статьи блога должна быть своя страница: /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));Приводите параметр к числу, когда сравниваете его с числовыми идентификаторами.