Роутинг

  1. Используется библиотека react-router.

  2. Маршруты описываются компонентным стилем в jsx в разметке контейнеров /app.

  3. Применяется вложенность контейнеров — маршрутизация подраздела внутри контейнера подраздела.

  4. Названия поддиректорий в /app соответствуют путям в маршрутах.

  5. Вне директории /app маршрутизация не допускается.

  6. Все контейнеры в директории /app прикреплены к какому-либо маршруту. За исключением модальных окон, для которых свой механизм навигации.

  7. Для программной навигации используется объект navigation — это прокси-объект к history api.

    • Везде где понадобится навигация — import navigation from "@src/app/navigation" .
    • Применяется вместо объекта history, который нужно доставать из контекста компонента.
    • Часто используемые переходы по маршрутам можно описать функциями в объекте navigation. Например: .goLogin() для перехода к форме входа вместо navigation.push('/login').
  8. Не использовать хук useParams() (и вообще все хуки роутера),

    • Брать параметр роутера из props.match.params в привязанном к маршруту контейнере-странице.
    • Вложенным контейнерам параметры маршрута пробрасываются вручную.
    • 👎 Хук useParams заставляет перерисовываться, даже если изменился не нужный контейнеру параметр. Аналогично негативно влияют на рендер все хуки роутера - useHistory(), useLocation(). Хук подписывает компонент на контекст роутера, а он меняется при любых действиях с навигацией.
  9. search параметры адреса не рассматривать как параметры роутера. Логику работы с ними лучше перенести в экшены редакса, там где могла бы быть логика работы с localStorage.

  10. Для получения и изменения search параметров использовать функции объекта navigation: .getSearchParams(), .setSearchParams().

Маршруты приложения в JSX

function App() {
  //...
  return (
    <Fragment>
      <Helmet>
        <title>Example</title>
      </Helmet>
      <Switch>
        <Route path="/" exact={true} component={Main} />
        <Route path="/catalog/:categoryId?" component={Catalog} />
        <Route path="/about" component={About} />
        <Route path="/login" component={Login} />
        <RoutePrivate path="/private" failpath="/login" component={Private} />
        <Route component={NotFound} />
      </Switch>
      <Modals />
    </Fragment>
  );
}