Вкладені маршрути

За допомогою маршрутизації можна описувати логіку навігації "підсторінок". Це коли за URL батьківського компонента відображається сторінка батьківського компонента, а при додатковому підмаршруті іще якийсь дочірній вкладений компонент.

Наприклад у нас є сторінка About (/about) на якій відображається якийсь контент про сайт

<Route path="/about" element={<About />} />

А ми хочемо прописати додаткові роути, щоб при переході на них у нас в межах цієї сторінки підвантажувався додатковий уточнюючий контент. Наприклад про команду(/about/team), про місію(/about/mission) і про засновників(/about/founders) та партнерів(/about/partners).

// НEправильно!
<Route path="/about" element={<About />} />
<Route path="/about/team" element={<Team />} />
<Route path="/about/mission" element={<Mission />} />
<Route path="/about/founders" element={<Founders />} />
<Route path="/about/partners" element={<Partners />} />

Якщо описати маршрути за схемою, вказаною вище, то всі вони будуть незалежними сторінками. А нам потрібно, щоб чотири компоненти були дочірніми і підвантажувалися у зарендерений батьківський компонент додатковим блоком (компонентом). В такому разі такі роути потрібно описати всередині батьківського роуту.

// Правильно!
<Route path="/about" element={<About />}>
    <Route path="team" element={<Team />} />
    <Route path="mission" element={<Mission />} />
    <Route path="founders" element={<Founders />} />
    <Route path="partners" element={<Partners />} />
</Route>

Характерні особливості:

  • Вкладені маршрути декларативно вкладають в батьківський маршрут

  • Вкладені маршрути описують відносно батьківського маршруту. Зверніть увагу НЕ повний шлях path="/about/team", а відносний path="team".

  • Відносні шляхи вказують без символу слеша /. НЕ path="/team", а path="team". Якщо напочатку поставити слеш, то маршрутизація зламається і буде створено новий окремий маршрут.

Повний код вкладеної маршрутизації наведено нижче:

App.jsx
import { Routes, Route, Link } from "react-router-dom";
import Home from "path/to/pages/Home";
import About from "path/to/pages/About";
import Reviews from "path/to/pages/Reviews";
import Works from "path/to/pages/Works";
import NotFound from "path/to/pages/NotFound";
import WorkDetails from "path/to/pages/WorkDetails";
import Team from "path/to/pages/Team";
import Mission from "path/to/pages/Mission";
import Founders from "path/to/pages/Founders";
import Partners from "path/to/pages/Partners";

export const App = () => {
  return (
    <div>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
        <Link to="/reviews">Reviews</Link>
        <Link to="/works">Works</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />}>
           <Route path="team" element={<Team />} />
           <Route path="mission" element={<Mission />} />
           <Route path="founders" element={<Founders />} />
           <Route path="partners" element={<Partners />} />
        </Route>
        <Route path="/reviews" element={<Reviews />} />
        <Route path="/works" element={<Works />} />
        <Route path="/works/:workId" element={<WorkDetails />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </div>
  );
};

Але цього недостатньо. Обовʼязково потрібно вказати де саме в батьківському компоненті (<About>) ми хочемо за дочірнім роутом підставити відповідний компонент. Для цього використовують спеціальний компонент <Outlet>.

src/pages/About.jsx
import { Link, Outlet } from "react-router-dom";

export const About = () => {
  return (
    <div>
      <h1>About page</h1>
      <ul>
        <li>
          <Link to="team">Read about team</Link>
        </li>
        <li>
          <Link to="mission">Read about mission</Link>
        </li>
        <li>
          <Link to="founders">Read about Founders</Link>
        </li>
        <li>
          <Link to="partners">Read about Partners</Link>
        </li>
      </ul>
      <Outlet />
    </div>
  );
};

Якщо URL в адресному рядку браузера збігається зі значенням prop path вкладеного маршруту, <Outlet> відрендерить його компонент, інакше він рендерить null та не впливає на розмітку батьківського компонента.

Характерні особливості:

Значення prop to компонента <Link>. так само як і значення prop path вкладеного маршруту - вказують відносно поточного URL.

Компонент <About> рендериться за адресою /about, тому посилання з to="team" буде вести на /about/team.

Якщо необхідно зробити посилання на іншу сторінку, тоді треба вказати шлях повністю, наприклад to="/works".

Нижче наведено живий приклад. Його код можна переглянути за цим посиланням.

Last updated