Хуки React Router

5 хв. читання

З п'ятою версією React Router з'являється підтримка хуків, за допомогою яких можна керувати роутингом.

Цей матеріал буде корисним для тих, хто хоче швидко ознайомитись з особливостями нового React Router. Але перше ніж перейти до хуків, оглянемо новий патерн рендерингу роутів.

До появи React Router 5

// Коли треба було відрендерити роут та передати пропси роутера в компонент
<Route path="/" component={Home} />

// Або коли треба було передати додаткові пропси 
<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.
  • Працює подібно до параметра нативного об'єкта браузера windowwindow.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.

Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 3.9K
Приєднався: 11 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація