React Router: Навігаційна система сучасного вебу

Динамічні Маршрути та Параметри

До цього моменту ми працювали з фіксованими URL: /about, /contact. Але реальні додатки працюють з динамічними даними: користувачі (/user/123), товари (/products/iphone-15) або замовлення (/order/abc-999).

Динамічні Маршрути та Параметри

До цього моменту ми працювали з фіксованими URL: /about, /contact. Але реальні додатки працюють з динамічними даними: користувачі (/user/123), товари (/products/iphone-15) або замовлення (/order/abc-999).

У цьому розділі ми навчимося "читати" змінні з URL.

1. Параметри шляху (URL Params)

Параметри шляху — це змінні частини URL, які ми позначаємо двокрапкою : у конфігурації.

Налаштування маршруту

Уявіть, що ми робимо сторінку деталей товару.

src/main.jsx
const router = createBrowserRouter([
    {
        path: '/',
        element: <RootLayout />,
        children: [
            {
                path: 'products',
                element: <ProductsPage />,
            },
            {
                // Двокрапка означає, що "productId" — це змінна
                path: 'products/:productId',
                element: <ProductDetailsPage />,
            },
        ],
    },
])

Тепер цей маршрут буде спрацьовувати для:

  • /products/1
  • /products/abc
  • /products/iphone-15

Читання параметрів: useParams

Щоб отримати значення цієї змінної всередині компонента, використовуємо хук useParams.

src/pages/ProductDetailsPage.jsx
import { useParams } from 'react-router-dom'

export default function ProductDetailsPage() {
    // Назва властивості збігається з тим, що ми вказали після двокрапки в роутері
    const params = useParams() // { productId: "..." }
    const { productId } = params

    return (
        <div>
            <h1>Деталі товару</h1>
            <p>ID товару: {productId}</p>
        </div>
    )
}
Важливо: Всі параметри, отримані з useParams, є рядками (string). Навіть якщо URL /products/123, productId буде "123". Якщо вам потрібне число для API, не забудьте зробити parseInt(productId) або Number(productId).

2. Пошукові параметри (Search Params / Query Strings)

Це параметри, які йдуть після знаку ? в URL. Наприклад: /products?sort=price&filter=samsung. Вони зазвичай використовуються для фільтрації, сортування або пагінації.

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

Хук useSearchParams

Цей хук працює дуже схоже на useState. Він повертає масив з двох елементів:

  1. Об'єкт URLSearchParams (для читання).
  2. Функцію setSearchParams (для запису).
src/pages/ProductsPage.jsx
import { useSearchParams } from 'react-router-dom'

export default function ProductsPage() {
    const [searchParams, setSearchParams] = useSearchParams()

    // Читання параметру "sort" з URL
    const sortOrder = searchParams.get('sort') // "asc", "desc" або null

    return (
        <div>
            <h1>Товари</h1>
            <p>Сортування: {sortOrder || 'за замовчуванням'}</p>

            <div className="filters">
                <button onClick={() => setSearchParams({ sort: 'asc' })}>Ціна: від дешевих</button>
                <button onClick={() => setSearchParams({ sort: 'desc' })}>Ціна: від дорогих</button>
                {/* Скидання параметрів */}
                <button onClick={() => setSearchParams({})}>Скинути</button>
            </div>
        </div>
    )
}

Збереження інших параметрів

Функція setSearchParams працює як навігація — вона замінює поточні параметри новими. Якщо у вас був URL ?filter=samsung&sort=asc і ви викличете setSearchParams({ page: 2 }), то filter і sort зникнуть. Новий URL буде ?page=2.

Щоб змінити тільки один параметр, зберігши інші, потрібно трохи "потанцювати":

function changePage(newPage) {
    setSearchParams((prevParams) => {
        // prevParams — це об'єкт URLSearchParams
        prevParams.set('page', newPage)
        return prevParams
    })
}

3. Практичний сценарій: Майстер-Деталь

Давайте поєднаємо все разом. У нас буде список користувачів. При кліку на користувача ми переходимо на його сторінку.

src/pages/UsersPage.jsx
import { Link } from 'react-router-dom'

const USERS = [
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' },
]

export default function UsersPage() {
    return (
        <ul>
            {USERS.map((user) => (
                <li key={user.id}>
                    {/* Формуємо динамічне посилання */}
                    <Link to={`/users/${user.id}`}>{user.name}</Link>
                </li>
            ))}
        </ul>
    )
}

Резюме

  • Params (:id): Частина шляху. Використовуйте для ідентифікації ресурсів (сторінка товару, профілю). Отримуємо через useParams.
  • Search Params (?sort=asc): Додаткові налаштування відображення. Отримуємо і змінюємо через useSearchParams.

Тепер ми можемо створювати складні URL. Але є одна проблема: ми досі завантажуємо дані (наприклад, інформацію про товар) у useEffect після того, як сторінка відкрилася. Це спричиняє "спіннери". У наступному розділі ми розглянемо Data API — революційний спосіб роботи з даними в React Router v6.4+.

Copyright © 2026