Хуки React Router

  • 27 марта, 15:23
  • 4644
  • 0

С пятой версией React Router появляется поддержка хуков, с помощью которых можно управлять роутингом.

Этот материал будет полезен для тех, кто хочет быстро ознакомиться с особенностями нового 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

  1. Хук дает доступ к параметру history React Router.
  2. Относится к history package : зависимости, которую использует сам роутер.
  3. Основное применение - роутинг, который задается явно с помощью push, replace и тому подобное.

import { useHistory } from 'react-router-dom';

function Home() {
  const history = useHistory();
  return <button onClick={() => history.push('/profile')}>Profile</button>;
}

useLocation

  1. Хук дает доступ к параметру location React Router.
  2. Работает подобно параметру нативного объекта браузера window- window.location, однако доступен везде и передает состояние роутера и текущее местоположение.
  3. Основной вариант использования - получение параметров запроса из строки маршрута.

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

  1. Хук дает доступ к параметрам поиска в URL;
  2. Раньше так можно было только с 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

  1. Хук дает доступ к объекту match;
  2. Если использовать его без аргументов, он возвращает точное совпадение среди роута компонента или его родительских компонентов;
  3. Основной вариант использования - создание вложенных маршрутов.

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 комментариев
Сортировка:
Добавить комментарий