Урок 04

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

Вложенные маршруты позволяют строить иерархию: общий layout для нескольких страниц, общий layout для секции.

Пример

<Routes>
    <Route path="/" element={<RootLayout />}>
        <Route index element={<Home />} />
        <Route path="posts" element={<PostsLayout />}>
            <Route index element={<PostsList />} />
            <Route path=":id" element={<PostDetail />} />
            <Route path="new" element={<NewPost />} />
        </Route>
        <Route path="about" element={<About />} />
    </Route>
</Routes>

Дерево:

/              → RootLayout + Home
/posts         → RootLayout + PostsLayout + PostsList
/posts/5       → RootLayout + PostsLayout + PostDetail
/posts/new     → RootLayout + PostsLayout + NewPost
/about         → RootLayout + About

RootLayout

import { Outlet } from 'react-router-dom';

function RootLayout() {
    return (
        <>
            <Header />
            <main className="container">
                <Outlet />
            </main>
            <Footer />
        </>
    );
}

Outlet — место, куда рендерится дочерний маршрут.

PostsLayout

function PostsLayout() {
    return (
        <div className="posts-layout">
            <aside>
                <PostsSidebar />
            </aside>
            <div>
                <Outlet />
            </div>
        </div>
    );
}

Общий сайдбар для списка, деталей и формы.

index-маршрут

<Route index element={<Home />} />

index — маршрут, который рендерится, когда родитель совпал, а дочерний путь — пустой. Для / — Home, для /posts — PostsList.

Вложенные динамические

<Route path="posts/:postId" element={<PostLayout />}>
    <Route index element={<PostView />} />
    <Route path="comments" element={<Comments />} />
    <Route path="related" element={<Related />} />
</Route>

URL: /posts/5, /posts/5/comments, /posts/5/related.

Несколько Outlet

Иногда нужно несколько точек вставки. Например, layout с двумя областями. Это решается через передачу элемента или через layout-компонент с двумя Outlet (в разных маршрутах). Обычно хватает одного.

Layout без пути

Иногда layout нужен без сегмента URL:

<Route element={<AuthLayout />}>
    <Route path="/login" element={<Login />} />
    <Route path="/register" element={<Register />} />
</Route>

path не указан — layout не добавляет сегмент.

Навигация в layout

NavLink внутри layout автоматически подсвечивает активный пункт:

<nav>
    <NavLink to="/" end>Главная</NavLink>
    <NavLink to="/posts">Посты</NavLink>
    <NavLink to="/about">О нас</NavLink>
</nav>

end — для главной, чтобы / не считался активным на всех маршрутах.

Итоги

  • Вложенные маршруты строят иерархию
  • Outlet — точка вставки дочернего
  • index — маршрут по умолчанию
  • Layout без path — общий без сегмента URL
  • NavLink с end для корня