С пятой версией React Router появляется поддержка хуков, с помощью которых можно управлять роутингом.
Этот материал будет полезен для тех, кто хочет быстро ознакомиться с особенностями нового React Router. Но прежде чем перейти к хукам, осмотрим новый паттерн рендеринга роута.
До появления React Router 5
// When you wanted to render the route and get router props for component
<Route path="/" component={Home} />
// Or when you wanted to pass extra props
<Route path="/" render={({ match }) => <Profile match={match} mine={true} />}>
Когда мы использовали параметр component для рендеринга соответствующего компонента, пропсы роутера match, location и history передавались ему автоматически. Однако для передачи дополнительных параметров, необходимо было использовать render.
Стоит помнить, передана в параметре component функция вызовет повторное монтирование компонента при каждом рендеринге.
После появления React Router 5
<Route path="/">
<Home />
</Route>
Обратите внимание на отсутствие дополнительных параметров в компоненте Home. Теперь вы можете, не меняя компонент Route, передать любые дополнительные пропсы дочернему компоненту. К тому же автоматически исправляется проблема с повторным монтажом компонента при каждом рендере.
Но теперь пропсы роутера не передаются неявно. Так как нам получить доступ к match, location и history? Надо теперь окутывать все компоненты withRouter? Здесь на помощь и приходят хуки.
Обратите внимание, что хуки было предложено в версии React 16.8, поэтому проверьте версию React в вашем проекте, прежде чем использовать их.
useHistory
- Хук дает доступ к параметру history React Router.
- Относится к history package : зависимости, которую использует сам роутер.
- Основное применение - роутинг, который задается явно с помощью push, replace и тому подобное.
import { useHistory } from 'react-router-dom';
function Home() {
const history = useHistory();
return <button onClick={() => history.push('/profile')}>Profile</button>;
}
useLocation
- Хук дает доступ к параметру location React Router.
- Работает подобно параметру нативного объекта браузера window- window.location, однако доступен везде и передает состояние роутера и текущее местоположение.
- Основной вариант использования - получение параметров запроса из строки маршрута.
import { useLocation } from 'react-router-dom';
function Profile() {
const location = useLocation();
useEffect(() => {
const currentPath = location.pathname;
const searchParams = new URLSearchParams(location.search);
}, [location]);
return <p>Profile</p>;
}
Поскольку свойство location неизменяемой, useEffect будет вызывать переданную функцию каждый раз, когда меняется роут. А это прекрасная возможность управлять параметрами поиска или текущим путем.
useParams
- Хук дает доступ к параметрам поиска в URL;
- Раньше так можно было только с match.params;
import { useParams, Route } from 'react-router-dom';
function Profile() {
const { name } = useParams();
return <p>{name}'s Profile</p>;
}
function Dashboard() {
return (
<>
<nav>
<Link to={`/profile/ann`}>Ann's Profile</Link>
</nav>
<main>
<Route path="/profile/:name">
<Profile />
</Route>
</main>
</>
);
}
useRouteMatch
- Хук дает доступ к объекту match;
- Если использовать его без аргументов, он возвращает точное совпадение среди роута компонента или его родительских компонентов;
- Основной вариант использования - создание вложенных маршрутов.
import { useRouteMatch, Route } from 'react-router-dom';
function Auth() {
const match = useRouteMatch();
return (
<>
<Route path={`${match.url}/login`}>
<Login />
</Route>
<Route path={`${match.url}/register`}>
<Register />
</Route>
</>
);
}
Вы также можете использовать useRouteMatch для доступа к совпадению маршрута, без необходимости рендерить Route. Для этого передайте в хук аргумент текущего маршрута.
Представьте, что вам необходимо, чтобы собственный профиль рендерился на роуте /profile, а роут профиля других пользователей содержал их имя, например /profile/dan, /profile/ann. До появления хуков для этого мы использовали Switch, чтобы перечислить оба роута и настроить их поведение с помощью пропсов. Но посмотрите, насколько просто это реализовать с помощью новых хуков.
import {
Route,
BrowserRouter as Router,
Link,
useRouteMatch,
} from 'react-router-dom';
function Profile() {
const match = useRouteMatch('/profile/:name');
return match ? <p>{match.params.name}'s Profile</p> : <p>My own profile</p>;
}
export default function App() {
return (
<Router>
<nav>
<Link to="/profile">My Profile</Link>
<br />
<Link to={`/profile/ann`}>Ann's Profile</Link>
</nav>
<Route path="/profile">
<Profile />
</Route>
</Router>
);
}
Вы до сих пор можете использовать все пропсы в Route - вроде exact и sensitive- как параметры объекта в useRouteMatch.
Вывод
Хуки и явные компоненты Route имеют преимущества, которых не видно на первый взгляд. Однако после использования их в реальных проектах можно увидеть, что это лучше предыдущих шаблоны, которые были в роутинге.
С хуками ваш код для роутинга станет более поддерживаемым, устойчивым к ошибкам и гибким для нововведений в следующих версиях React Router.
0 комментариев
Добавить комментарий