Подробные примеры для React Router
Для веб-приложения маршрутизация — это механизм отображения всей или частичной страницы на основе предоставленного URL-адреса, параметров или действий пользователя с кнопкой, ссылкой, значком и т. д.
Сам React не включает маршрутизацию. react-router
совместим с последними версиями React и является наиболее популярным выбором маршрутизации для приложений React. React Router позволяет перемещаться между представлениями различных компонентов. Он считывает и контролирует URL-адрес браузера, а также поддерживает синхронизацию пользовательского интерфейса с URL-адресом.
React Router 6 был выпущен 3 ноября 2021 года. Давайте подробно рассмотрим, как его использовать.
Терминология навигации
Во-первых, мы рассмотрим некоторые термины, которые часто используются при навигации в браузере.
URL-адрес
URL-адрес (унифицированный указатель ресурса) — это адрес данного уникального ресурса в Интернете. В браузере есть адресная строка, в которую пользователи могут вводить определенный URL-адрес или заполнять ее программно.
Интерфейс URL
используется для анализа, создания, нормализации и кодирования URL-адресов. Он имеет ряд свойств, которые можно читать и изменять.
Создайте URL-адрес:
const url = new URL('https://john:[email protected]:8080/users/?id=5#profile');
Вот сгенерированный объект:
url.searchParams.get('id')
возвращает 5.
Расположение
Местоположение — это объект, который представляет местоположение URL. Он основан на объекте window.location
браузера.
Введите URL-адрес www.google.com
в адресной строке браузера, а window.location
будет установлено следующее значение:
Вот определения Path
и Location
в React Router:
История
Существует два API истории, которые отслеживают историю браузера и управляют ею:
history
API: он отслеживает URL-адреса основного фрейма, которые пользователь посещал на любой вкладке в течение всего срока действия профиля.History
интерфейс: он управляет историей сеансов браузера. то есть он отслеживает навигацию на каждой вкладке.
Поскольку интерфейс History
более осмыслен в современных браузерах, window.history
включает запись для History
. Вот пример window.history
:
Вот определение History
в React Router:
Настройка рабочей среды
React Router публикуется с 3 пакетами:
react-router
содержит большую часть основных функций React Router, включая алгоритм сопоставления маршрутов и большинство основных компонентов и перехватчиков.react-router-dom
включает все изreact-router
и добавляет несколько специфичных для DOM API, включая<BrowserRouter>
,<HashRouter>
и<Link>
.react-router-native
включает в себя все изreact-router
и добавляет несколько API, характерных для React Native, в том числе<NativeRouter>
и нативную версию<Link>
.
Для веб-приложений все, что нам нужно, это react-router-dom
.
Как всегда, строим среду Create React App:
npx create-react-app react-router cd react-router
Настройте react-router-dom
:
npm i react-router-dom
Кроме того, устанавливается lorem-ipsum
для генерации текста-заполнителя lorem ipsum для страниц. Текст Lorem ipsum обычно используется в качестве заполнителя в издательском деле, графическом дизайне и веб-разработке.
npm i lorem-ipsum
react-router-dom
и lorem-ipsum
становятся частью dependencies
в package.json
.
Настройка маршрутов
Router — это компонент верхнего уровня с отслеживанием состояния, который заставляет работать все остальные компоненты навигации и хуки. React Router имеет BrowserRouter
, HashRouter
, StaticRouter
, NativeRouter
и MemoryRouter
. Для веб-приложений обычно используется BrowserRouter
. Приложение должно иметь один <BrowserRouter>
, обертывающий один или несколько <Routes>
.
<Routes>
проверяет все свои children
<Route>
элементы, чтобы найти наилучшее соответствие, и отображает эту часть пользовательского интерфейса.
<Route>
определяется как объект или элемент маршрута. Если это объект, объект имеет форму { path, element }
. Если это элемент Route, компонент имеет форму <Route path element>
. Когда шаблон пути соответствует текущему URL-адресу, отображается реквизит element
.
Подготавливаем несколько страниц для управления в src/Pages.js
:
Строки 3–10 определяют функцию getPage
. Он генерирует озаглавленную страницу, где содержимое страницы генерируется loremIpsum()
с 5 случайными предложениями (строка 7).
Функция getPage
используется для генерации PageOne
(строка 12) и PageTwo
(строка 13). Вот так выглядит PageOne
, и PageTwo
похоже.
В src/App.js
создаются два маршрута:
<BrowserRouter>
и <Routes>
используются для определения маршрутизатора (строки 6–11).
В приложении есть два <Route>
. Когда URL-адрес соответствует пути "one"
, приложение показывает PageOne
(строка 8). Когда URL-адрес соответствует пути, "two"
, приложение показывает PageTwo
(строка 9).
Запустите приложение, выполнив команду npm start
.
https://localhost:3000/one
показывает PageOne
.
https://localhost:3000/two
показывает PageTwo
.
Приложение работает для путей "one"
и "two"
. Однако https://localhost:3000
ничего не показывает, как и любые недопустимые URL-адреса, такие как https://localhost:3000/anything
.
Эту проблему можно решить с помощью подстановочного пути (строка 8):
https://localhost:3000/two
показывает PageTwo
. В противном случае отображается PageOne
.
Поскольку React Router 6 достаточно умен, чтобы выбрать наиболее точное совпадение, порядок маршрута не имеет значения.
Настройка вложенных маршрутов
Два маршрута в приведенном выше примере работают, как и ожидалось. Однако вводить URL-адрес в адресной строке браузера неудобно. Мы хотели бы иметь возможность навигации, нажав на ссылку, которая является <Link>
.
<Link>
отображает доступный элемент <a>
с реальным href
, указывающим на ресурс, на который он ссылается. Щелчок по ссылке устанавливает URL-адрес и отслеживает историю просмотров.
src/MainPage.js
создается с помощью <Link>
s:
Строки 4–13 определяют элемент <nav>
с набором навигационных ссылок.
Строка 7 — это ссылка, указывающая на путь "/one"
. Текст ссылки "Page One"
.
Строка 10 — это ссылка, указывающая на путь "/two"
. Текст ссылки "Page Two"
.
Значения <Link to>
могут относиться к пути маршрута, который их отображает. т. е. путь указан без ведущего /
. Альтернативно, строка 7 может указывать на "one"
, а строка 10 может указывать на "two"
.
Используйте MainPage
в src/App.js
:
Строка 9 — это маршрут index
, который является дочерним маршрутом без пути. Когда URL соответствует "/"
, приложение показывает MainPage
. Вот индексная страница:
Нажав на ссылку Page One
, вы попадете на PageOne
. Нажав на ссылку Page Two
, вы попадете на PageTwo
.
Однако внутри PageOne
или PageTwo
мы не можем использовать ссылки для навигации. Чтобы решить эту проблему, мы создаем компонент <Outlet>
в MainPage
. Выходной компонент отображает следующее совпадение ("one"
для PageTwo
и "two"
для PageTwo
) в пути.
Это src/MainPage.js
с розеткой:
Строка 15 — это элемент <hr>
, который представляет собой горизонтальное правило для разделения контента.
Строка 16 — это компонент <Outlet>
для рендеринга активного дочернего маршрута.
<Outlet>
вызывает вложенные маршруты, где каждый маршрут может иметь дочерние маршруты, занимающие часть URL-адреса. Вложенные маршруты обычно используют относительные ссылки (строка 8 и строка 11).
Вот модифицированный src/App.js
:
В строке 9 маршрут верхнего уровня — "/"
, и он отображает компонент MainPage
. Под ним есть три дочерних маршрута:
- Индексный маршрут (строка 10): показывает текст
No page is selected
.
- Маршрут с подстановочными знаками (строка 11): показывает компонент
PageOne
.
- Маршрут
"two"
(строка 12): показывает компонентPageTwo
.
Хук useRoutes
Вместо <Routes>
мы также можем использовать хук useRoutes
, чтобы выполнить то же самое.
Вложенные маршруты в src/App.js
можно переписать с помощью useRoutes
:
В строках 6–16 мы используем ловушку useRoutes
для создания объекта routes
из структуры данных.
Мы должны создать AppWrapper
, чтобы обернуть routes
внутри <browserRouter>
(строки 20–26). В противном случае мы столкнемся со следующей ошибкой:
Error: useRoutes() may be used only in the context of a component.
использованиеМестоположение
Местоположение — это объект, который представляет местоположение URL. Он основан на объекте window.location
браузера.
Хук useLocation
возвращает объект текущего местоположения.
В строке 7 location
генерируется хуком useLocation
.
Строки 8–10 определяют useEffect
, который регистрирует значение местоположения, если оно изменяется.
- Когда URL-адрес равен
https://localhost:3000/
, консоль регистрирует:
Current location is {pathname: '/', search: '', hash: '', state: null, key: 'default'}
- Когда URL-адрес равен
https://localhost:3000/one
, консоль регистрирует:
Current location is {pathname: '/one', search: '', hash: '', state: null, key: 'f2114bru'}
- Когда URL-адрес равен
https://localhost:3000/two
, консоль регистрирует:
Current location is {pathname: '/two', search: '', hash: '', state: null, key: 'if9ngy0q'}
- Когда URL-адрес равен
https://localhost:3000/anything
, консоль регистрирует:
Current location is {pathname: '/anything', search: '', hash: '', state: null, key: 'default'}
Хук useParams
Чтобы сделать пример более интересным, мы вложили больше маршрутов. На MainPage
кроме ссылок на "Page One"
и "Page Two"
есть более подробные ссылки на "P1"
(пункт 1) и "P2"
(пункт 2).
Вот модифицированный src/App.js
:
Под путем "one"
(строка 23) есть еще один дочерний маршрут с динамическим параметром ":id"
(строка 25).
По пути "two"
(строка 28) есть еще один дочерний маршрут с динамическим параметром ":id"
(строка 30).
Вот модифицированный src/MainPage.js
:
Рядом со ссылкой "Page One"
добавляются ссылки P1
(путь "one/1"
) и P2 (путь "one/2"
) (строки 9–10).
Рядом со ссылкой "Page Two"
добавляются ссылки P1
(путь "two/1"
) и P2
(путь "two/2"
) (строки 13–14).
Хук useParams
возвращает объект пар ключ/значение динамических параметров из текущего URL. Вот модифицированный src/Pages.js
с использованием хука useParams
:
Поскольку хук должен использоваться в компоненте React, строки 4–14 заменяют функцию getPage
на компонент BuildPage
.
Строка 5 использует хук useParams
для получения динамического пути id
. Значение id
отображается в начале содержимого (строка 10).
Строка 14 генерирует PageOne
через BuildPage
.
Строка 15 генерирует PageTwo
через BuildPage
.
Когда URL-адрес равен https://localhost:3000/one/1
, консоль регистрирует:
Current location is {pathname: '/one/1', search: '', hash: '', state: null, key: 'qpdrrtyg'}
useNavigate
Хук useNavigate
возвращает функцию, которую можно использовать для программной навигации. Замените два <Link>
s на <button>
s в src/MainPage.js
:
Строка 4 возвращает хук useNavigate
.
Строки 10–12 определяют кнопку "Page One"
, где обработчик onClick
перемещается по относительному пути "one"
.
Строки 16–18 определяют кнопку "Page Two"
, где обработчик onClick
перемещается по относительному пути "two"
.
Запустите приложение. Кнопки действуют аналогично ссылкам.
Функция navigate
имеет две подписи:
- Передайте значение
To
(того же типа, что и<Link to>
) с необязательным вторым аргументом,{ replace, state }
. - Передайте дельта-число, чтобы войти в стек истории. Например,
navigate(-1)
эквивалентно нажатию кнопки «Назад».
Другие крючки
Мы показали, как использовать useLocation
, useNavigate
, useParams
и useRoutes
.
Есть и другие хуки React Router:
useHref
: возвращает URL-адрес, который можно использовать для ссылки на указанноеto
местоположение даже за пределами React Router.useLinkClickHandler
: возвращает обработчик события клика для навигации при создании пользовательской ссылки.useInRouterContext
: возвращаетtrue
, если компонент визуализируется в контексте<Router>
,false
в противном случае.useNavigationType
: возвращает способ перехода пользователя на текущую страницу черезAction.Pop
,Action.Push
илиAction.Replace
в стеке истории.useMatch
: возвращает данные соответствия о маршруте по заданному пути относительно текущего местоположения.useOutlet
: возвращает элемент дочернего маршрута на этом уровне иерархии маршрутов.useResolvedPath
: Сопоставляетpathname
местоположения в заданном значенииto
с путем к текущему местоположению.useSearchParams
: используется для чтения и изменения строки запроса в URL-адресе для текущего местоположения.
Заключение
React Router 6 многофункционален и прост в использовании. Он совместим с последними версиями React. Поскольку он содержит несколько критических изменений по сравнению с версией 5, рекомендуется дождаться выпуска пакета обратной совместимости, прежде чем обновлять приложения.
Спасибо за прочтение. Я надеюсь, что это было полезно. Если вам интересно, ознакомьтесь с другими моими статьями на Medium.
Примечание. Спасибо Уриану Чангу и Джошу Брауну за то, что вместе со мной оценили React Router 6.