Маршруты могут принимать параметры. Параметр имеет следующую форму определения: :название_параметра
.
Например, используем параметры:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Маршруты в React</title> </head> <body> <div id="app"></div> <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/history@5/umd/history.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-router@6.3.0/umd/react-router.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-router-dom@6.3.0/umd/react-router-dom.production.min.js" crossorigin></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> const Router = ReactRouterDOM.BrowserRouter; const Route = ReactRouterDOM.Route; const Routes = ReactRouterDOM.Routes; const useParams = ReactRouterDOM.useParams; const Outlet = ReactRouterDOM.Outlet; 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( <Router> <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> </Router> ); </script> </body> </html>
Для получения параметров маршрута применяется встроенная функция-хук useParams, соответственно ее вначале необходимо получить:
const useParams = ReactRouterDOM.useParams;
Здесь определен один маршрут, который принимает параметр:
<Route path=":id" element={<Product />} />
Причем он определен как дочерний по отношению к маршруту "/products". То есть к подобному ресурсу нам надо будет обращаться по адресу, к примеру
http://localhost:3000/products/5
где 5 - значение для параметра id. Этот маршрут будет обрабатываться компонентом Product. Причем надо учитывать, что хуки могут применяться только в функциональных компонентах. Поэтому компонент Product определен в виде функции:
function Product(){ // получаем параметры const params = useParams(); const prodId = params.id; return <h2>Товар № {prodId}</h2>; }
Функция useParams() возвращает набор параметров маршрута. Фактически такой набор представляет объект, а каждый отдельный параметр - свойство этого объекта.
И чтобы получить параметр id, необходимо использовать выражение params.id
.
Если же параметр не будет передан, например, при запросе http://localhost:3000/products, то он будет обрабатываться компонентом ProductsList.
И в зависимости от наличия параметра мы получим тот или иной результат:
Стоит отметить, что поскольку функции-хуки, типа useParams, можно использовать только в функциональных компонентах, то напрямую использовать в компонентах=классах
мы ее не можем. И при использовании компонентов-классов одно из распространенных решений состоит в том, чтобы компонент, который использует
useParams()
, сделать функциональным:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Маршруты в React</title> </head> <body> <div id="app"></div> <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/history@5/umd/history.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-router@6.3.0/umd/react-router.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-router-dom@6.3.0/umd/react-router-dom.production.min.js" crossorigin></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> const Router = ReactRouterDOM.BrowserRouter; const Route = ReactRouterDOM.Route; const Routes = ReactRouterDOM.Routes; const useParams = ReactRouterDOM.useParams; const Outlet = ReactRouterDOM.Outlet; 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( <Router> <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> </Router> ); </script> </body> </html>
Подобным образом мы можем использовать и большее количество параметров. Например, изменим компонент Product и его маршрут:
const Router = ReactRouterDOM.BrowserRouter; const Route = ReactRouterDOM.Route; const Routes = ReactRouterDOM.Routes; const useParams = ReactRouterDOM.useParams; const Outlet = ReactRouterDOM.Outlet; function ProductsList(){ return <h2>Список товаров</h2>;} function Product(){ // получаем параметры const params = useParams(); const prodId = params.id; const prodName = params.name; return <h2>Id: {prodId} Name: {prodName}</h2>; } function Products(){ return (<div> <h1>Товары</h1> <Outlet /> </div>); } ReactDOM.createRoot( document.getElementById("app") ) .render( <Router> <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> </Router> );
Теперь компонент Product получает два параметра - id и name:
При этом необязательно для получения параметров определять вложенные маршруты, например, сократим код следующим образом:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Маршруты в React</title> </head> <body> <div id="app"></div> <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/history@5/umd/history.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-router@6.3.0/umd/react-router.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-router-dom@6.3.0/umd/react-router-dom.production.min.js" crossorigin></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> <script type="text/babel"> const Router = ReactRouterDOM.BrowserRouter; const Route = ReactRouterDOM.Route; const Routes = ReactRouterDOM.Routes; const useParams = ReactRouterDOM.useParams; function Products(){ const params = useParams(); const prodId = params.id; const prodCat = params.cat; return <h2>Товар id: {prodId} категория: {prodCat}</h2>; } ReactDOM.createRoot( document.getElementById("app") ) .render( <Router> <div> <Routes> <Route path="/" element={<h2>Главная</h2>} /> <Route path="/products/:id/:cat" element={<Products />}/> <Route path="*" element={<h2>Ресурс не найден</h2>} /> </Routes> </div> </Router> ); </script> </body> </html>
В то же время маршруту по пути "/products/:id/:cat" обязательно надо передать два параметра, если мы передадим в запросе только один параметр, то данный запрос будет обрабатываться последним маршрутом.