Введение в getServerSideProps
Сегодня мы переходим к одной из самых мощных функций в Next.js — getServerSideProps. Этот инструмент позволяет извлекать данные непосредственно на сервере перед рендерингом страницы. Это ключевой момент для реализации Server-Side Rendering (SSR), который мы уже начали разбирать. Если раньше мы гоняли данные прямо в браузер, теперь будем чуть более изысканны — пусть сервер поработает за нас.
Итак, главная героиня сегодняшнего дня — функция getServerSideProps. Она — подарок от Next.js для серверного рендеринга. Её задача — подготовить все необходимые данные на сервере до того, как страница будет визуализирована.
Основная концепция
getServerSideProps — это асинхронная функция, которая вызывается на сервере при каждом запросе к странице. Её работа — собрать и передать необходимые данные вашему React-компоненту как пропсы.
Схема работы getServerSideProps:
Клиент -> Сервер (Запрос) -> getServerSideProps -> Получение данных -> Рендеринг -> Ответ клиенту
Почему это важно?
- SEO: поисковые боты получают готовую страницу с контентом.
- Динамические данные: в отличие от статических страниц, данные обновляются при каждом запросе.
- Управление сложными состояниями: можно извлекать данные из API, баз данных или других источников прямо перед рендерингом.
Как использовать getServerSideProps
Создадим базовую страницу. Для начала достаточно добавить функцию getServerSideProps в вашем файле:
// pages/example.tsx
import { GetServerSideProps } from 'next';
interface ExampleProps {
message: string;
}
export const getServerSideProps: GetServerSideProps<ExampleProps> = async (context) => {
// Здесь мы можем извлекать данные из API, БД и т.д.
const message = "Привет с сервера!";
return {
props: {
message,
},
};
};
const ExamplePage = ({ message }: ExampleProps) => {
return (
<div>
<h1>{message}</h1>
</div>
);
};
export default ExamplePage;
Что здесь происходит?
- Мы определили функцию
getServerSideProps, которая возвращает объект с полемprops. - Эти
propsстановятся доступными компоненту, связанному с этой страницей. - Типизация функции выполнена через
GetServerSideProps<ExampleProps>.
Запустите сервер npm run dev, перейдите на страницу /example — и вы увидите сообщение с сервера!
Разберём контекст getServerSideProps
getServerSideProps предоставляет вам доступ к объекту context. Давайте разберём, что внутри:
type GetServerSidePropsContext = {
params?: ParsedUrlQuery; // Параметры маршрута
req: IncomingMessage; // Запрос пользователя
res: ServerResponse; // Ответ сервера
query: ParsedUrlQuery; // Query параметры (например, ?id=123)
resolvedUrl: string; // Полный URL маршрута
locale?: string; // Локализация, если включена
preview?: boolean; // Режим предпросмотра
};
Пример использования контекста:
export const getServerSideProps: GetServerSideProps = async (context) => {
const { query } = context;
const id = query.id || "нет ID";
return {
props: { id },
};
};
Если открыть /example?id=123, вы сможете извлечь параметр id.
Пример: Получение данных с API
Пора добавить немного реальной работы. Представьте, что у нас есть API, который возвращает информацию о пользователях.
// pages/user/[id].tsx
import { GetServerSideProps } from 'next';
interface User {
id: number;
name: string;
email: string;
}
interface UserPageProps {
user: User | null;
}
export const getServerSideProps: GetServerSideProps<UserPageProps> = async (context) => {
const { id } = context.params!; // Берём параметр из маршрута (например, /user/1)
try {
const res = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
const user: User = await res.json();
return {
props: { user },
};
} catch (error) {
return {
props: { user: null }, // Если произошла ошибка
};
}
};
const UserPage = ({ user }: UserPageProps) => {
if (!user) {
return <div>Пользователь не найден.</div>;
}
return (
<div>
<h1>{user.name}</h1>
<p>Email: {user.email}</p>
</div>
);
};
export default UserPage;
Теперь страница /user/1 покажет данные пользователя с ID 1. Если ID не существует, вы увидите сообщение "Пользователь не найден."
Обработка ошибок и состояния загрузки
Не все запросы к API или базе данных проходят идеально. Давайте добавим обработку ошибок. Например, если API возвращает статус 404:
export const getServerSideProps: GetServerSideProps = async (context) => {
try {
const res = await fetch(`https://jsonplaceholder.typicode.com/users/invalid-id`);
if (!res.ok) {
throw new Error(`Ошибка сервера: ${res.status}`);
}
const user = await res.json();
return {
props: { user },
};
} catch (error) {
console.error("Ошибка при загрузке данных:", error);
return {
notFound: true, // Это заставляет Next.js вернуть статус 404
};
}
};
Теперь, если данные недоступны, Next.js автоматически покажет страницу 404!
Ограничения getServerSideProps
Конечно, как у любой технологии, здесь есть свои "но". Вот несколько важных моментов, которые стоит учитывать:
- Производительность:
getServerSidePropsвыполняется при каждом запросе. Если сервер перегружен или API отвечает медленно, это может негативно сказаться на времени загрузки страницы. - Кэширование: контент, рендерящийся через
getServerSideProps, не может быть кэширован CDN. Для кэширования используйтеgetStaticProps. - Сложность: всё, что вы делаете в этой функции, происходит на сервере, а не на клиенте. Это требует четкого понимания сетевой логики и обработки данных на уровне сервера.
Зачем это нужно?
Вы можете использовать функциональность getServerSideProps для:
- Создания динамических страниц, которые всегда содержат актуальные данные.
- Улучшения SEO за счёт предварительного рендеринга контента.
- Загрузки данных, требующих аутентификации или конфиденциальности (на сервере данные безопаснее).
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ