Загрузка данных в маршрутах
Загрузка данных в маршрутах — это процесс получения информации (например, с API), необходимой для отображения конкретного экрана. В React Router v6 основной подход заключается в том, что каждый компонент маршрута отвечает за загрузку собственных данных.
Загрузка в компоненте маршрута
Наиболее распространённый способ — инициировать запрос при монтировании компонента, используя useEffect:
// UserProfile.jsx
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
function UserProfile() {
const { userId } = useParams();
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(res => res.json())
.then(data => {
setUser(data);
setLoading(false);
});
}, [userId]);
if (loading) return <div>Загрузка...</div>;
return <div>Имя: {user.name}</div>;
}
Каждый маршрут сам управляет своим состоянием загрузки, ошибками и обновлением данных при изменении параметров (например, переходе от /user/1 к /user/2).
Принцип инкапсуляции
Важно, чтобы данные загружались в том компоненте, который их использует. Например, если страница профиля отображает список постов пользователя, запрос к /api/users/:id/posts должен выполняться внутри UserProfile, а не в родительском компоненте. Это:
- упрощает логику;
- предотвращает передачу ненужных пропсов;
- делает компоненты переиспользуемыми.
Альтернатива: loader-функции (React Router v6.4+)
Начиная с версии 6.4, React Router предлагает новый подход — loader-функции, которые выполняются до рендеринга компонента. Они позволяют загружать данные на этапе маршрутизации, а не в самом компоненте:
// routes.js
const userLoader = async ({ params }) => {
const res = await fetch(`/api/users/${params.userId}`);
return res.json();
};
<Route path="/user/:userId" element={<UserProfile />} loader={userLoader} />
Однако в рамках текущего курса мы фокусируемся на базовом подходе с useEffect, так как он:
- работает во всех версиях React Router v6;
- не требует дополнительной настройки роутера;
- проще для понимания на начальном этапе.
Рекомендации
- Не загружайте данные в родительском компоненте ради дочернего — это нарушает инкапсуляцию;
- Обрабатывайте ошибки загрузки (например, показывайте сообщение при 404 от API);
- Используйте
userIdизuseParams()как зависимость вuseEffect, чтобы обновлять данные при смене параметра.
Этот подход обеспечивает чёткое разделение ответственности и предсказуемое поведение при навигации.