Індексні маршрути

На більшості інтернет-сайтів певна частина інтерфейсу лишається незмінно. Наприклад шапка, підвал, бокове меню тощо. А при навігації по сайту змінюється лише вміст головного контейнера.

Немає сенсу на кожній сторінці дублювати цю розмітку. Можна зробити спільну обгортку із компонентів, які не змінюються, а при навігації по сайту змінювати тільки головний вміст. Для цього використовують прийом «shared layout».

src/components/App.jsx
// Import libraries and components

export const App = () => {
  return (
    <Container>
      <Header>
        <Logo>
          <span role="img" aria-label="logo icon">
            🙈
          </span>
          Monkey Studio
        </Logo>
        <nav>
           <Link to="/">Home</Link>
           <Link to="/about">About</Link>
           <Link to="/reviews">Reviews</Link>
           <Link to="/works">Works</Link>
        </nav>
      </Header>
      <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>
    </Container>
  );
};

У прикладі вище, головне меню навігації зверстано у файлі App.jsx. При нарощенні проєкту, стилізаційні елементи сильно перенавантажуватимуть App.jsx. Прийнято у файлі App.jsx прописувати тільки правила маршрутизації, без зайвого контенту, а всі стилізаційні компоненти та верстання незмінного блоку виносити в окремі блоки.

Тож, винесемо розмітку і стилі незмінної обгортки в окремий компонент <SharedLayout>. Там де ми плануємо рендерити змінну частину сайту в залежності маршруту на якому перебуваємо - вказуємо компонент <Outlet>.

Після цього потрібно використати компонент <SharedLayout> в компоненті <App>. Пропишемо так, щоб він рендерився на всіх маршрутах вкажемо його маршрут path="/". Вкладемо у нього всі інші маршрути АЛЕ маршрути пропишемо відносно батьківського Shared Layout - тобто prop path без символу /.

Тут видно, що за базовим маршрутом path="/" тепер рендериться тільки компонент <SharedLayout> без <Home>. Хоча за іншими вкладеними маршрутами рендериться як <SharedLayout>, так і той компонент у якого збігається path зі значенням в адресному рядку. Тобто за маршрутом path="about" зрендериться компонент <SharedLayout> і <About>.

Щоб виправити цей ньюанс і за базовим маршрутом рендерити <Home> компонент за тим же маршрутом необхідно створити індексний маршрут.

Індексним може бути лише вкладений маршрут. В його <Route> не вказують prop path, тому що він збігається зі значенням path батька. Замість цього передають спеціальний prop index, який вказує бібліотеці React Router, що цей маршрут треба відрендерити на ту ж адресу, що і його батько.

Індексних маршрутів може бути довільна кількість залежно від поставленого завдання. Наприклад, у панелі адміністратора можна рендерити інший інтерфейс і відповідно підключити інший <SharedLayout>.

Нижче наведено живий приклад на маршрутизацію із SharedLayout. Проглянути код можна тут.

Last updated