Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Вложенные маршруты и макеты

У страниц блога одинаковые шапка, меню и подвал, меняется только середина. Вместо того чтобы повторять их в каждой странице, делают макет (layout) — компонент с общими частями и местом для текущей страницы. Маршруты страниц вкладывают внутрь маршрута макета, а место для них отмечают компонентом Outlet.

Компонент макета

Создайте src/components/Layout.jsx:

// src/components/Layout.jsx
import { Outlet } from 'react-router';
import Nav from './Nav.jsx';
 
export default function Layout() {
  return (
    <>
      <header>
        <Nav />
      </header>
      <main>
        <Outlet />
      </main>
      <footer>Блог, 2026</footer>
    </>
  );
}

Outlet — место, куда React Router подставит компонент вложенного маршрута, совпавшего с адресом.

Вложенные маршруты

В src/App.jsx маршруты страниц переносят внутрь маршрута макета:

// src/App.jsx
import { Route, Routes } from 'react-router';
import Layout from './components/Layout.jsx';
import HomePage from './pages/HomePage.jsx';
import AboutPage from './pages/AboutPage.jsx';
import PostPage from './pages/PostPage.jsx';
 
export default function App() {
  return (
    <Routes>
      <Route element={<Layout />}>
        <Route index element={<HomePage />} />
        <Route path="about" element={<AboutPage />} />
        <Route path="posts/:id" element={<PostPage />} />
        <Route path="*" element={<p>Страница не найдена</p>} />
      </Route>
    </Routes>
  );
}

Откройте /, /about и /posts/3 — на всех трёх страницах будут меню и подвал, а в main — своя страница. Nav из App теперь можно убрать: он живёт в макете.

Индексный маршрут

index вместо path означает «показать, когда адрес совпадает с адресом родителя». У макета без пути родитель — корень /, поэтому HomePage показывается на главной.

ЗаписьАдрес
Route indexАдрес родителя, здесь /
Route path="about"/about
Route path="posts/:id"/posts/3

Пути вложенных маршрутов пишут без начального / — они продолжают путь родителя.

Вложенность внутри страницы

Вложенными могут быть и сами страницы. Пусть у статьи будет вкладка комментариев по адресу /posts/3/comments:

// src/App.jsx
<Route path="posts/:id" element={<PostPage />}>
  <Route path="comments" element={<PostComments />} />
</Route>
// src/pages/PostPage.jsx
import { Link, Outlet } from 'react-router';
 
// в конце разметки статьи:
<Link to="comments">Показать комментарии</Link>
<Outlet />

По ссылке адрес станет /posts/3/comments, и под статьёй появится компонент PostComments. Путь comments в Link относительный — он добавляется к текущему адресу. Компонент PostComments читает id тем же useParams и загружает /posts/3/comments из API.

Частая ошибка

Если в макете забыть Outlet, вложенные страницы не появятся — на всех адресах будут только шапка и подвал:

// Неправильно: некуда вывести страницу.
export default function Layout() {
  return (
    <>
      <Nav />
      <footer>Блог, 2026</footer>
    </>
  );
}

Каждый маршрут, у которого есть дочерние маршруты, должен выводить Outlet в своём компоненте.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.