Параметры маршрутов

Последнее обновление: 21.03.2025

Маршруты могут принимать параметры. Параметр имеет следующую форму определения: :название_параметра.

Например, используем параметры:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
    <div id="app"></div>

    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

    <script type="text/babel" data-type="module">
        import React from "https://esm.sh/react@19?dev";
        import ReactDOM from "https://esm.sh/react-dom@19/client?dev";
        import { BrowserRouter, Routes, Route, Outlet, useParams } from "https://esm.sh/react-router-dom@7?dev";
  
        function ProductsList(){ return <h2>Список товаров</h2>;}
        function Product(){
            // получаем параметры
            const params = useParams();
            const prodId = params.id;
            return <h2>Товар № {prodId}</h2>;
        }
        function Products(){
            return (<div>
                    <h1>Товары</h1>
                    <Outlet />
                </div>);
        }
        ReactDOM.createRoot(
            document.getElementById("app")
        )
        .render(
            <BrowserRouter>
                <div>
                <Routes>
                    <Route path="/" element={<h2>Главная</h2>} />
                    <Route path="/products" element={<Products />}>
                        <Route index element={<ProductsList />} />
                        <Route path=":id" element={<Product />} />
                    </Route>
                    <Route path="*" element={<h2>Ресурс не найден</h2>} />
                </Routes>
                </div>
            </BrowserRouter>
        );
    </script>
</body>
</html>

Здесь определен один маршрут, который принимает параметр:

<Route path=":id" element={<Product />} />

Причем он определен как дочерний по отношению к маршруту "/products". То есть к подобному ресурсу нам надо будет обращаться по адресу, к примеру

http://localhost:3000/products/5

где 5 - значение для параметра id. Этот маршрут будет обрабатываться компонентом Product. Для получения параметров маршрута применяется встроенная функция-хук useParams:

function Product(){
	// получаем параметры
	const params = useParams();
	const prodId = params.id;
	return <h2>Товар № {prodId}</h2>;
}

Функция useParams() возвращает набор параметров маршрута. Фактически такой набор представляет объект, а каждый отдельный параметр - свойство этого объекта. И чтобы получить параметр id, необходимо использовать выражение params.id.

Если же параметр не будет передан, например, при запросе http://localhost:3000/products, то он будет обрабатываться компонентом ProductsList.

И в зависимости от наличия параметра мы получим тот или иной результат:

Параметры маршрутов в React Передача параметров в React

Стоит отметить, что поскольку функции-хуки, типа useParams, можно использовать только в функциональных компонентах, то напрямую использовать в компонентах=классах мы ее не можем. И при использовании компонентов-классов одно из распространенных решений состоит в том, чтобы компонент, который использует useParams(), сделать функциональным:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
    <div id="app"></div>

    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

    <script type="text/babel" data-type="module">
        import React from "https://esm.sh/react@19?dev";
        import ReactDOM from "https://esm.sh/react-dom@19/client?dev";
        import { BrowserRouter, Routes, Route, Outlet, useParams } from "https://esm.sh/react-router-dom@7?dev";
  
        class ProductsList extends React.Component{
            render(){
                return <h2>Список товаров</h2>;
            }
        }
        function Product(){
            // получаем параметры
            const params = useParams();
            const prodId = params.id;
            return <h2>Товар № {prodId}</h2>;
        }
        class Products extends React.Component{
            render(){
                return (<div>
                    <h1>Товары</h1>
                    <Outlet />
                </div>)
            }
        }
        ReactDOM.createRoot(
            document.getElementById("app")
        )
        .render(
            <BrowserRouter>
                <div>
                <Routes>
                    <Route path="/" element={<h2>Главная</h2>} />
                    <Route path="/products" element={<Products />}>
                        <Route index element={<ProductsList />} />
                        <Route path=":id" element={<Product />} />
                    </Route>
                    <Route path="*" element={<h2>Ресурс не найден</h2>} />
                </Routes>
                </div>
            </BrowserRouter>
        );
    </script>
</body>
</html>

Подобным образом мы можем использовать и большее количество параметров. Например, изменим компонент Product и его маршрут:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
    <div id="app"></div>

    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

    <script type="text/babel" data-type="module">
        import React from "https://esm.sh/react@19?dev";
        import ReactDOM from "https://esm.sh/react-dom@19/client?dev";
        import { BrowserRouter, Routes, Route, Outlet, useParams } from "https://esm.sh/react-router-dom@7?dev";
  
        function ProductsList(){ return <h2>Список товаров</h2>;}
        
        function Product(){
            // получаем параметры
            const {id, name} = useParams();
            return <h2>Id: {id}   Name: {name}</h2>;
        }
        function Products(){
        return (<div>
                    <h1>Товары</h1>
                    <Outlet />
                </div>);
        }
        ReactDOM.createRoot(
            document.getElementById("app")
        )
        .render(
            <BrowserRouter>
                <div>
                <Routes>
                    <Route path="/" element={<h2>Главная</h2>} />
                    <Route path="/products" element={<Products />}>
                        <Route index element={<ProductsList />} />
                        <Route path=":id/:name" element={<Product />} />
                    </Route>
                    <Route path="*" element={<h2>Ресурс не найден</h2>} />
                </Routes>
                </div>
            </BrowserRouter>
        );
    </script>
</body>
</html>

Теперь компонент Product получает два параметра - id и name:

Параметры в маршрутах в React

При этом необязательно для получения параметров определять вложенные маршруты, например, сократим код следующим образом:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
    <div id="app"></div>

    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

    <script type="text/babel" data-type="module">
        import React from "https://esm.sh/react@19?dev";
        import ReactDOM from "https://esm.sh/react-dom@19/client?dev";
        import { BrowserRouter, Routes, Route, Outlet, useParams } from "https://esm.sh/react-router-dom@7?dev";
  
        function Products(){
            const {id, cat} = useParams();
            return <h2>Товар id: {id}   категория: {cat}</h2>;
        }
        ReactDOM.createRoot(
            document.getElementById("app")
        )
        .render(
            <BrowserRouter>
                <div>
                <Routes>
                    <Route path="/" element={<h2>Главная</h2>} />
                    <Route path="/products/:id/:cat" element={<Products />}/>
                    <Route path="*" element={<h2>Ресурс не найден</h2>} />
                </Routes>
                </div>
            </BrowserRouter>
        );
    </script>
</body>
</html>
Параметры в маршрутах в React-Router-Dom

В то же время маршруту по пути "/products/:id/:cat" обязательно надо передать два параметра, если мы передадим в запросе только один параметр, то данный запрос будет обрабатываться последним маршрутом.

Необязательные параметры

С помощью вопросительного знака (?) можно отметить параметр как необязательный:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
    <div id="app"></div>

    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

    <script type="text/babel" data-type="module">
        import React from "https://esm.sh/react@19?dev";
        import ReactDOM from "https://esm.sh/react-dom@19/client?dev";
        import { BrowserRouter, Routes, Route, Navigate, NavLink, useParams } from "https://esm.sh/react-router-dom@7?dev";
  
        const users =
        [
            {id: 1, name: "Tom"}, 
            {id: 2, name: "Bob"}, 
            {id: 3, name: "Sam"} 
        ];

        function Home(){ return <h2>Главная</h2>; }
        function Users(){
            // получаем параметры
            const {id} = useParams();
            // если id передан, возвращаем конкретного пользователя
            if(id){
                const user = users.find(u=>u.id == id);
                if(user===undefined) return <h2>Пользователь не найден</h2>;
                else return <h2>Пользователь {user.name}</h2>;
            }
            // иначе возвращаем список пользователей
            return (
                <>
                    <h2>Список пользователей</h2>
                    <ul>
                    {
                        users.map(function(user){
                            return <li key={user.id}>
                                    <NavLink to={`/users/${user.id}`}>{user.name}</NavLink>
                                </li>
                        })
                    }
                    </ul>
                </>
            );
        }
        ReactDOM.createRoot(
            document.getElementById("app")
        )
        .render(
            <BrowserRouter>
                <div>
                <Routes>
                    <Route path="/" element={<h2>Главная</h2>} />
                    <Route path="/users/:id?" element={<Users />} />
                    <Route path="*" element={<h2>Ресурс не найден</h2>} />
                </Routes>
                </div>
            </BrowserRouter>
        );
    </script>
</body>
</html>

В данном случае для компонента Users параметр "id" отмечен как необязательный:

<Route path="/users/:id?" element={<Users />} />

В компоненте Users получаем параметр id:

function Users(){
    const {id} = useParams();

Причем даже если он не передан, то он все равно будет доступен, просто будет равен null. Соответственно далее мы можем проверить параметр на null. Если параметр передан, то получаем пользователя по переданному id из массива users:

if(id){
    const user = users.find(u=>u.id == id);
    if(user===undefined) return <h2>Пользователь не найден</h2>;
    else return <h2>Пользователь {user.name}</h2>;
}

Иначе выводим весь список пользователей:

Необязательные параметры маршрутов в React
Помощь сайту
Юмани:
410011174743222
Номер карты:
4048415020898850