Українська

Дослідіть паралельні маршрути Next.js: повний посібник зі створення динамічних, гнучких макетів сторінок з кількома незалежними секціями. Дізнайтеся про реалізацію, переваги та найкращі практики.

Паралельні маршрути Next.js: створення динамічних макетів сторінок

Next.js, провідний фреймворк React, постійно розвивається, щоб надавати розробникам потужні інструменти для створення сучасних вебзастосунків. Однією з найцікавіших функцій, представлених в останніх версіях, є паралельні маршрути (Parallel Routes). Ця функція дозволяє рендерити кілька незалежних секцій в межах одного макета сторінки, пропонуючи неперевершену гнучкість і контроль над структурою вашого застосунку та користувацьким досвідом.

Що таке паралельні маршрути?

Традиційно маршрут у Next.js відповідає одному компоненту сторінки. Коли ви переходите на інший маршрут, вся сторінка перерендериться. Паралельні маршрути ламають цю парадигму, дозволяючи рендерити декілька компонентів одночасно в межах одного макета, кожен з яких керується власним незалежним сегментом маршруту. Уявіть, що ви ділите свою сторінку на окремі секції, кожна з яких має власну URL-адресу та життєвий цикл, і всі вони співіснують на одному екрані.

Це відкриває багато можливостей для створення більш складних та динамічних користувацьких інтерфейсів. Наприклад, ви можете використовувати паралельні маршрути для:

Розуміння концепції: Слоти

Основною концепцією паралельних маршрутів є поняття "слотів". Слот — це іменована область у вашому макеті, де рендериться певний сегмент маршруту. Ви визначаєте ці слоти у вашій директорії app, використовуючи символ @, за яким слідує назва слота. Наприклад, @sidebar представляє слот з назвою "sidebar".

Кожен слот може бути пов'язаний із сегментом маршруту. Коли користувач переходить на певний маршрут, Next.js рендерить компонент, пов'язаний з цим сегментом маршруту, у відповідний слот у макеті.

Реалізація: практичний приклад

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

1. Структура директорій

Спочатку визначимо структуру директорій для нашого застосунку:

app/
  product/
    [id]/
      @cart/
        page.js  // Компонент кошика
      page.js      // Компонент з деталями товару
    layout.js   // Макет товару
  layout.js     // Кореневий макет

Ось що представляє кожен файл:

2. Кореневий макет (app/layout.js)

Кореневий макет зазвичай містить елементи, які є спільними для всього застосунку, наприклад, хедери та футери.

// app/layout.js
export default function RootLayout({ children }) {
  return (
    
      
        
Мій E-commerce застосунок
{children}
© 2024
); }

3. Макет товару (app/product/[id]/layout.js)

Це ключова частина, де ми визначаємо наші слоти. Ми отримуємо компоненти для основної сторінки товару та кошика як пропси, що відповідають page.js та @cart/page.js відповідно.

// app/product/[id]/layout.js
export default function ProductLayout({ children, cart }) {
  return (
    
{children}
); }

У цьому прикладі ми використовуємо простий макет flexbox для розміщення основного контенту товару та бічної панелі кошика поруч. Пропс children міститиме відрендерений результат app/product/[id]/page.js, а пропс cart міститиме відрендерений результат app/product/[id]/@cart/page.js.

4. Сторінка з детальною інформацією про товар (app/product/[id]/page.js)

Це стандартна сторінка динамічного маршруту, яка відображає деталі товару на основі параметра id.

// app/product/[id]/page.js
export default async function ProductDetails({ params }) {
  const { id } = params;
  // Отримання даних товару за ID
  const product = await fetchProduct(id);

  return (
    

Деталі товару

{product.name}

{product.description}

Ціна: ${product.price}

); } async function fetchProduct(id) { // Замініть на вашу реальну логіку отримання даних return new Promise(resolve => setTimeout(() => { resolve({ id, name: `Товар ${id}`, description: `Опис Товару ${id}`, price: 99.99 }); }, 500)); }

5. Компонент кошика (app/product/[id]/@cart/page.js)

Цей компонент представляє кошик, який буде рендеритися у слоті @cart.

// app/product/[id]/@cart/page.js
export default function ShoppingCart() {
  return (
    

Кошик

Товарів у кошику: 3

); }

Пояснення

Коли користувач переходить на /product/123, Next.js:

  1. Відрендерить кореневий макет (app/layout.js).
  2. Відрендерить макет товару (app/product/[id]/layout.js).
  3. В межах макета товару відрендерить компонент деталей товару (app/product/[id]/page.js) у пропс children.
  4. Одночасно відрендерить компонент кошика (app/product/[id]/@cart/page.js) у пропс cart.

Результатом є сторінка з детальною інформацією про товар з постійною бічною панеллю кошика, все відрендерено в одному макеті.

Переваги використання паралельних маршрутів

Що слід враховувати та найкращі практики

Розширене використання: умовний рендеринг та динамічні слоти

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

Умовний рендеринг

Ви можете умовно рендерити різні компоненти у слоті залежно від ролей користувача, статусу автентифікації або інших факторів.

// app/product/[id]/layout.js
import { getUserRole } from '../../utils/auth';

export default async function ProductLayout({ children, cart }) {
  const userRole = await getUserRole();

  return (
    
{children}
); } function AdminPanel() { return (

Панель адміністратора

Керуйте деталями товару тут.

); }

У цьому прикладі, якщо користувач має роль 'admin', у слоті @cart буде відрендерено компонент AdminPanel замість кошика.

Динамічні слоти

Хоча це менш поширено, теоретично ви *можете* динамічно створювати назви слотів, але це, як правило, не рекомендується через складність та потенційні наслідки для продуктивності. Краще дотримуватися заздалегідь визначених і добре зрозумілих слотів. Якщо виникає потреба в динамічних "слотах", розгляньте альтернативні рішення, такі як використання стандартних компонентів React з пропсами та умовним рендерингом.

Реальні приклади та випадки використання

Розглянемо деякі реальні приклади того, як паралельні маршрути можна використовувати в різних типах застосунків:

Висновок

Паралельні маршрути Next.js — це потужна функція, яка відкриває новий світ можливостей для створення динамічних та гнучких вебзастосунків. Дозволяючи рендерити кілька незалежних секцій в межах одного макета сторінки, паралельні маршрути дають змогу створювати більш захопливі користувацькі досвіди, підвищувати повторне використання коду та спрощувати процес розробки. Хоча важливо враховувати потенційні складнощі та дотримуватися найкращих практик, оволодіння паралельними маршрутами може значно покращити ваші навички розробки на Next.js і дозволити вам створювати справді інноваційні вебзастосунки.

Оскільки Next.js продовжує розвиватися, паралельні маршрути, безсумнівно, стануть все більш важливим інструментом для розробників, які прагнуть розширити межі можливого в Інтернеті. Експериментуйте з концепціями, викладеними в цьому посібнику, і дізнайтеся, як паралельні маршрути можуть трансформувати ваш підхід до створення сучасних вебзастосунків.