Этот урок посвящен созданию динамических страниц — страниц, контент которых меняется в зависимости от параметров URL-адреса.
Обработка URL-адресов
На текущий момент на главной странице отображаются все записи, а ссылки на отдельные записи имеют формат /post/[ID], где [ID] — идентификатор записи. Для обработки таких URL-адресов:
- Создайте папку post. Имя папки соответствует началу пути в URL, а квадратные скобки [] указывают на динамический параметр.
- Внутри папки post создайте файл page.js. Этот файл будет содержать компонент для отображения отдельной записи.
В файле page.js создайте компонент:
import React from 'react';
export default async function Post({ params }) {
const post = await fetchPostData(params.id);
return (
<h1>{post.title}</h1>
);
}
async function fetchPostData(id) {
const res = await fetch(`/api/post/${id}`);
return res.json();
}
Этот код получает параметр id из URL-адреса через params.id и отображает заголовок статьи, полученный с помощью функции fetchPostData. Например, /post/10 отобразит заголовок статьи с ID 10.
Получение и отображение данных
Функция fetchPostData делает запрос к API по адресу /api/post/${id} и возвращает данные в формате JSON. В компоненте Post эта функция вызывается с параметром params.id, полученным из URL.
Форматирование и навигация
Для улучшения отображения информации, используйте теги <h2>, <p> и <strong>:
<h2>{post.title}</h2>
<p>{post.body}</p>
<strong>Автор: {post.userId}</strong>
Для навигации «Назад» используйте компонент Link из next/link:
import Link from 'next/link';
<Link href="/">
<a>Назад</a>
</Link>
Оптимизация с помощью отдельных компонентов
Для повышения производительности и улучшения структуры кода, реализуем вывод статьи через отдельный компонент post.js. Этот компонент будет получать данные статьи в качестве пропсов.
Создайте файл post.js с компонентом:
import React from 'react';
export default function Post({ post }) {
return (
<div className="post">
<h2>{post.title}</h2>
<p>{post.body}</p>
<strong>Автор: {post.userId}</strong>
</div>
);
}
В файле page.js импортируйте и используйте этот компонент:
import Post from './component/post';
import Link from 'next/link';
export default async function PostPage({ params }) {
const post = await fetchPostData(params.id);
return (
<div>
<Link href="/">
<a>Назад</a>
</Link>
<Post post={post} />
</div>
);
}
async function fetchPostData(id) {
const res = await fetch(`/api/post/${id}`);
return res.json();
}
Теперь вывод статьи осуществляется через отдельный компонент, что улучшает структуру кода и упростит добавление клиентской логики в будущем.