Роутинг связывает URL с тем, что видит пользователь: какой экран показать, какие данные ему нужны, пускать ли вообще. В React-стеке стандарт — React Router. Понять его модель (маршруты, вложенность, параметры, защита) — значит уметь собирать навигацию, которая масштабируется на десятки экранов.
Маршруты и вложенность
Маршрут сопоставляет путь компоненту. Маршруты вкладывают друг в друга: общий layout (шапка, навигация) — снаружи, конкретные экраны — внутри, через Outlet.
import { Routes, Route, Outlet } from "react-router-dom";
function AppLayout() {
return (
<div>
<Header />
<main><Outlet /></main>
</div>
);
}
function AppRoutes() {
return (
<Routes>
<Route element={<AppLayout />}>
<Route path="/products" element={<ProductList />} />
<Route path="/products/:id" element={<ProductDetails />} />
</Route>
</Routes>
);
}
Outlet — место, куда подставляется вложенный маршрут. Это та же композиция, что у компонентов: layout задаёт рамку, маршруты — содержимое. Вложенность держит навигацию структурной, а не плоским списком из полусотни путей.
Параметры и навигация
Динамическую часть пути (:id) достают через useParams; программный переход — через useNavigate.
function ProductDetails() {
const { id } = useParams();
const product = useProduct(id); // TanStack Query по id
// ...
}
function CreateButton() {
const navigate = useNavigate();
return <button onClick={() => navigate("/products/new")}>Создать</button>;
}
Параметр маршрута обычно становится частью ключа запроса (["product", id]) — URL и данные согласованы: меняется адрес — меняются данные.
Загрузка данных по маршруту
Есть два подхода. Первый — данные грузит компонент экрана через TanStack Query (как выше): просто и в одном инструменте для всего серверного состояния. Второй — data-router с loader-ами, где данные маршрута загружаются до отрисовки экрана. Для большинства приложений хватает первого; loader-ы полезны, когда важно не показывать экран без данных и убрать промежуточные состояния загрузки. Выбор — по потребности, без догмы.
Защищённые маршруты
Доступ к маршруту по аутентификации — обёртка, которая пускает или перенаправляет на вход. Это frontend-аналог guard: проверка на границе экрана.
function RequireAuth({ children }: { children: React.ReactNode }) {
const user = useCurrentUser();
if (!user) return <Navigate to="/login" replace />;
return <>{children}</>;
}
<Route
path="/account"
element={<RequireAuth><Account /></RequireAuth>}
/>
Важно помнить границу: это удобство интерфейса, не безопасность. Реальную проверку прав делает backend на каждом запросе — клиент лишь не показывает то, чего пользователю не положено. Прятать кнопку без серверной проверки — дыра.
Где это в UCP
Роутинг — это карта продукта: какие экраны есть, как между ними двигаться, что доступно. Вложенность даёт структуру, параметры связывают URL с данными, защищённые маршруты — удобную (но не доверенную) границу доступа. Это позволяет продукт-инженеру держать навигацию растущего продукта осмысленной; а как всё это выглядит — вопрос стилизации.