Программная навигация с использованием React Router
Страницы на современных веб-сайтах, и особенно одностраничные приложения (SPA), не следуют традиционному методу полной загрузки новых страниц всякий раз, когда на них что-то меняется. Вместо этого используется маршрутизация на стороне клиента — для маршрутизации к ресурсам для загрузки другой части программы или структурного изменения всего представления приложения, если это необходимо, когда выполняется действие (например, нажатие кнопки или ссылки).
React — это очень популярная библиотека для фронтенд-разработки, используемая для создания высокочувствительных пользовательских интерфейсов и естественно, у нее есть собственный Router, который выполняет маршрутизацию на стороне клиента — файл react-router-dom
.
В этом руководстве мы рассмотрим, как создавать маршруты в приложении React, программно перемещаться между маршрутами, а также отправлять и получать данные между ними с помощью React Router.
Создание React-приложения
Давайте начнем с создания простого приложения React через командную строку:
npx create-react-app router-sample
После создания давайте перейдем в каталог проекта и запустим приложение:
cd router-sample
npm start
Это запустит сервер на localhost:3000
, и ваш браузер по умолчанию запустится для обслуживания приложения. Прежде чем создавать какие-либо новые файлы для этой конечной точки, давайте установим react-router-dom
, так как он не поставляется предварительно упакованным.
Установка React Router
Как обычно, установить пакет с помощью npm
так же просто, как выполнить одну команду:
npm install react-router-dom
Создание новых маршрутов с помощью React Router
Пакет react-router-dom
позволяет легко создавать новые маршруты. Для начала вы оборачиваете все приложение тегом <BrowserRouter>
. Мы делаем это, чтобы получить доступ к объекту браузера history
. Затем вы определяете ссылки на маршрутизатор, а также компоненты, которые будут использоваться для каждого маршрута.
Чтобы продемонстрировать это, давайте создадим новый файл с именем About.js
в папке /src
:
const About = () => {
return (
<div>
<h1>About page here!</h1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Fugit, modi!
</p>
</div>
);
};
export default About;
Теперь давайте обновим страницу src/index.js
и импортируем About
из только что созданного файла. Внутри тега <BrowserRouter>
мы определим наши маршруты и связанные с ними компоненты:
import { render } from "react-dom";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import App from "./App";
import About from "./About";
render(
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
<Route path="about" element={<About />} />
</Routes>
</BrowserRouter>,
document.getElementById("root")
);
Мы импортировали здесь <BrowserRouter>
и обернули в него все наше приложение. Мы также выбрали App.js
в качестве компонента для нашей домашней страницы (под конечной точкой /
) и About.js
в качестве компонента для страницы /about
.
Наконец, давайте адаптируем файл App.js
, который, опять же, будет основной точкой входа для приложения и нашей домашней страницей:
import { Link } from "react-router-dom";
function App() {
return (
<div className="App">
<h1>Welcome to my react app!</h1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusamus,
pariatur?
</p>
<br />
<Link to="/about">About Page</Link>
</div>
);
}
export default App;
На этом этапе мы создали два маршрута: входной маршрут (/
) и /about
, и мы должны иметь возможность легко перемещаться с домашней страницы на страницу сведений при посещении нашего приложения:
React Router Hooks (методы навигации)
Хуки были добавлены в React недавно, они являются функциями, которые позволяют вам «подключаться» в состояние приложения, без необходимости писать новые классы. React Router поставляется с несколькими хуками, которые позволяют нам программно получать доступ к состоянию маршрутизатора и перемещаться между компонентами. Среди них следующие хуки:
useHistory()
userNavigate()
useLocation()
useParams()
Чтобы использовать любой из этих хуков, мы должны сначала импортировать их из пакета react-router-dom
, а затем указать переменную, которая вызывает хук; мы рассмотрим это более подробно в следующих разделах.
useHistory()
Примечание. ХукuseHistory()
устарел в последней версии React Router. Если вы используете React Router V6, вам лучше использоватьuseNavigate()
. Он вызывается сразу после useHistory().
Хук useHistory()
обеспечивает прямой доступ к истории React Router, что позволяет нам выполнять действия, как получение количества записей в стеке истории, добавив, изменения или удаления записи из стека, и так далее.
Вот некоторые из наиболее полезных методов:
goBack()
- Вернуться назад в истории.goForward()
- Идите вперед в истории.push()
- Добавить новую запись в стек истории, т. е. перейти к новому URL-адресу.replace()
- Аналогиченpush()
тем, что заменяет текущий стек в истории, но в отличие отpush()
, пользователь не может вернуться назад в историю, т.е. нажатие кнопки браузера назад не вернет в предыдущее состояние.
С помощью всего этого мы можем программно переходить с нашей страницы About
на домашнюю страницу, вводя новую запись в историю, эффективно направляя пользователя к новой записи:
import React from "react";
import { useHistory } from "react-router-dom";
const About = () => {
let history = useHistory();
const goHome = () => {
history.push("/");
};
return (
<div>
<h1>About page here!</h1
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Fugit, modi!
</p>
<button onClick={goHome}>Go to home page</button>
</div>
);
};
export default About;
Здесь мы просто импортируем хук useHistory()
и создаем новую функцию goHome()
, которая выполняется по нажатию кнопки. Это просто оболочка для вызова push()
.
Мы также можем передавать состояние или отправлять произвольные данные на маршрут, по которому мы идем. Мы можем сделать это, отправив методу push объект вместо имени пути в виде строки и добавив наше состояние в отдельный объект:
history.push({
pathname: '/blog,
search: '?blogId=12, // Query string
state: { // Location state
author_name: "John Doe",
},
});
После покрытия useNavigate()
, мы будем смотреть на то, как получить доступ к этой информации с помощью useLocation()
и useParams()
.
useNavigate()
Если вы используете самую последнюю версию React Router, хук useHistory()
устарел в пользу useNavigate()
. Подход почти идентичен; основное отличие состоит в том, что useNavigate()
не принимает такие методы, как .push()
или .replace()
. Вы просто используете navigate()
:
import React from "react";
import { useNavigate } from "react-router-dom";
const About = () => {
let navigate = useNavigate();
const goHome = () => {
navigate("/");
};
return (
<div>
<h1>About page here!</h1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Fugit, modi!
</p>
<button onClick={goHome}>Go to home page</button>
</div>
);
};
export default About;
И, конечно же, этот метод также позволяет нам передавать состояния между маршрутами:
navigate("/blog", { state: { author_name: "John Doe" } });
Получение данных между маршрутами с помощью useLocation() и useParams()
Хук useLocation()
обеспечивает нам доступ к объекту браузера location
. Считайте это хуком, отвечающим за получение необходимой информации о текущем маршруте:
import { useNavigate, useLocation } from "react-router-dom";
/*...*/
let location = useLocation();
console.log(location);
Выполнение приведенного выше кода должно вернуть всю информацию о текущем маршруте, как показано ниже:
{
"pathname": "/about",
"search": "",
"hash": "",
"state": null,
"key": "default"
}
Разумно думать о хуке useLocation()
как о useState()
, который обновляет состояние на новое место всякий раз, когда изменяется URL-адрес. С другой стороны, userParams()
можно использовать для получения значения параметров URL. При вызове useParams()
предоставляет объект, который сопоставляет имена параметров URL-адреса с их значениями в текущем URL-адресе.
Например, в нашей конфигурации маршрутизатора допустим, что у нас есть динамический маршрут:
<Route path="/about/:user_id">
<About />
</Route>
А на другой странице у нас есть компонент ссылки, который указывает на некоторую информацию, относящуюся к Пользователю 2:
<Link to="/about/2">About User 2</Link>
Когда параметры передаются, как мы видели раньше, мы можем получить доступ к параметрам через хук userParams()
:
import { useParams } from "react-router-dom";
const About = () => {
const { user_id } = useParams();
return (
<div>
<h1>About user {user_id}</h1>
<p>
Lorem ipsum dolor...
</p>
</div>
);
};
export default About;