Шпаргалка по маршрутизатору React: все, что вам нужно знать

Если вы создаете приложения React для Интернета, вам понадобится специальный маршрутизатор для отображения страниц и навигации пользователя по ним.

Вот почему сегодня мы рассмотрим самый популярный и самый мощный маршрутизатор для приложений React - React Router.

Мы собираемся рассмотреть более 11 основных функций, которые вам необходимо знать, если вы используете React Router в своих проектах сегодня, особенно для Интернета, используя пакет react-router-dom.

Хотите свою копию? 📄

Нажмите здесь, чтобы загрузить шпаргалку в формате PDF (это займет 5 секунд).

Здесь вся необходимая информация представлена ​​в виде удобного руководства в формате PDF.

Установите React Router

Самый первый шаг к использованию React Router - это установка соответствующего пакета.

Технически это три разных пакета: React Router, React Router DOM и React Router Native.

Основное различие между ними заключается в их использовании. React Router DOM предназначен для веб-приложений, а React Router Native - для мобильных приложений, созданных с помощью React Native.

Первое, что вам нужно сделать, это установить React Router DOM с помощью npm (или пряжи):

npm install react-router-dom

Базовая настройка маршрутизатора

После его установки мы можем ввести наш первый компонент, который требуется для использования маршрутизатора React, и он называется BrowserRouter.

Есть несколько типов маршрутизаторов, которые react-router-dom предоставляет помимо BrowserRouter, которые мы не будем вдаваться в подробности. При импорте обычно используется псевдоним (переименование) BrowserRoute как просто «Маршрутизатор».

Если мы хотим предоставить маршруты в рамках всего нашего приложения, его необходимо обернуть вокруг всего нашего дерева компонентов. Вот почему вы обычно видите его обернутым вокруг основного компонента приложения или внутри него:

import { BrowserRouter as Router } from 'react-router-dom';

export default function App() {
  return (
    <Router>
      {/* routes go here, as children */}
    </Router>
  );
}

Это основная функция BrowserRouter: возможность объявлять отдельные маршруты в нашем приложении.

Обратите внимание, что любые данные, относящиеся к маршрутизатору, недоступны за пределами компонента маршрутизатора. Например, мы не можем получить доступ к данным истории за пределами маршрутизатора (то есть с помощью хука useHistory), и мы не можем создать маршрут вне компонента маршрутизатора.

Компонент маршрута

Следующий компонент - это компонент Route.

Мы объявляем маршруты в компоненте Router как дочерние. Мы можем объявить столько маршрутов, сколько захотим, и нам нужно предоставить как минимум два свойства для каждого маршрута, path и component (или render):

import { BrowserRouter as Router, Route } from 'react-router-dom';

export default function App() {
  return (
    <Router>
      <Route path="/about" component={About} />
    </Router>
  );
}

function About() {
  return <>about</>   
}

Свойство path указывает, на каком пути нашего приложения находится данный маршрут.

Например, для страницы about мы можем захотеть, чтобы этот маршрут был доступен по пути «/ about».

Свойство render или component используется для отображения определенного компонента для нашего пути.

Свойство component может получать только ссылку на данный компонент, тогда как render чаще используется для применения некоторой условной логики для отрисовки одного маршрута того или иного компонента. Для рендеринга вы можете использовать ссылку на компонент или функцию:

import { BrowserRouter as Router, Route } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Route path="/" render={() => <Home />} />
      <Route path="/about" component={About} />
    </Router>
  );
}

function Home() {
  return <>home</>;
}

function About() {
  return <>about</>;
}

Стоит отметить, что вы потенциально можете полностью отказаться от свойства render или component и использовать компонент, который вы хотите связать с данным маршрутом, как дочерний для Route:

import { BrowserRouter as Router, Route } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Route path="/about">
        <About />
      </Route>
    </Router>
  );
}

Наконец, если вы хотите, чтобы компонент (например, панель навигации) был виден на каждой странице, поместите его по-прежнему в маршрутизатор браузера, но выше (или ниже) объявленных маршрутов:

import { BrowserRouter as Router, Route } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Navbar />
      <Route path="/" component={Home} />
      <Route path="/about" component={About} />
    </Router>
  );
}

function Navbar() {
  // visible on every page
  return <>navbar</>
}

function Home() {
  return <>home</>;
}

function About() {
  return <>about</>;
}

Компонент переключателя

Когда мы начнем добавлять несколько маршрутов, мы заметим нечто странное.

Допустим, у нас есть маршрут для домашней страницы и страницы о странице. Несмотря на то, что мы указываем два разных пути, «/» и «/ about», когда я захожу на страницу about, мы увидим как компоненты home, так и about.

Мы можем исправить это с помощью точной опоры на домашнем маршруте, чтобы убедиться, что наш маршрутизатор точно соответствует пути «/» вместо «/ about»:

import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Navbar />
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
      </Switch>
    </Router>
  );
}

Когда дело доходит до переключения между разными маршрутами, которые должен показать наш маршрутизатор, на самом деле существует специальный компонент, который вы должны использовать, если у вас есть несколько маршрутов в вашем маршрутизаторе, и это компонент Switch.

Компонент коммутатора должен быть включен в маршрутизатор, и мы можем разместить в нем все наши маршруты:

import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Navbar />
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
      </Switch>
    </Router>
  );
}

Компонент switch просматривает все свои дочерние маршруты и отображает первый, путь которого совпадает с текущим URL-адресом.

Этот компонент - то, что мы хотим использовать в большинстве случаев для большинства приложений, потому что у нас есть несколько маршрутов и несколько страниц номеров в нашем приложении, но мы хотим отображать только одну страницу за раз.

Если по какой-то причине вы хотите, чтобы несколько страниц отображались одновременно, вы можете не использовать компонент переключения.

404 Маршрут

Если мы попытаемся пойти по пути, которого нет в нашем приложении, что мы увидим?

Мы ничего не увидим, если у нас не будет соответствующего маршрута. Как составить комплексный маршрут?

Если пользователь пытается перейти на страницу, для которой у нас нет определенного маршрута, мы можем создать маршрут, а затем указать путь к звездочке *:

import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Navbar />
      <Switch>
        <Route path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="*" component={NotFound} />
      </Switch>
    </Router>
  );
}

function NotFound() {
  return <>You have landed on a page that doesn't exist</>;
}

Это будет соответствовать любой попытке посетить страницу, которая не существует, и мы можем связать ее с ненайденным компонентом, чтобы сообщить нашим пользователям, что они «попали на страницу, которой не существует».

Компонент связи

Предположим, что в нашем NavBar мы действительно хотим создать некоторые ссылки, чтобы нам было легче перемещаться по нашему приложению, вместо того, чтобы изменять URL-адрес вручную в браузере.

Мы можем сделать это с помощью другого специального компонента из React Router DOM, который называется компонентом Link. Он принимает свойство to, которое указывает, куда мы хотим, чтобы ссылка переместила нашего пользователя. В нашем случае у нас может быть ссылка на дом и о нас:

import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Navbar />
      <Switch>
        <Route path="/" component={Home} />
        <Route path="/about" component={About} />
      </Switch>
    </Router>
  );
}

function Navbar() {
  return (
    <nav>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
    </nav>
  )
}

Компонент ссылки позволяет нам предоставлять некоторые встроенные стили, как и любой стандартный компонент React. Это также дает нам полезную component опору, поэтому мы можем установить нашу ссылку в качестве собственного настраиваемого компонента для еще большего упрощения стиля.

Компонент NavLink

Кроме того, React Router DOM предоставляет нам полезный компонент NavLink. в том случае, если мы хотим применить какие-то особые стили.

Если мы находимся на текущем пути, на который указывает ссылка, это позволяет нам создавать некоторые активные стили ссылок, чтобы по нашей ссылке сообщать нашим пользователям, на какой странице они находятся.

Например, если наши пользователи находятся на домашней странице, мы могли бы сообщить им об этом, используя опору activeStyle, чтобы сделать нашу ссылку жирной и красной, когда они находятся на главной странице:

import {
  BrowserRouter as Router,
  Switch,
  Route,
  NavLink
} from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Navbar />
      <Switch>
        <Route path="/" component={Home} />
        <Route path="/about" component={About} />
      </Switch>
    </Router>
  );
}

function Navbar() {
  return (
    <nav>
      <NavLink
        activeStyle={{
          fontWeight: "bold",
          color: "red"
        }}
        to="/"
      >
        Home
      </NavLink>
      <NavLink activeClassName="active" to="/about">
        About
      </NavLink>
    </nav>
  );
}

Существует также опора activeClassName, которую также можно установить, если вы не хотите включать встроенные стили или хотите, чтобы больше повторно используемых стилей выполняли ту же функцию, что и activeStyle.

Компонент перенаправления

Еще один очень полезный компонент, который дает нам React Router DOM, - это компонент перенаправления.

Может показаться странным наличие компонента, который выполняет функцию перенаправления нашего пользователя при его отображении, но это очень функционально. Каждый раз, когда мы используем что-то вроде частного маршрута и у нас есть условие, при котором пользователь не аутентифицирован, мы хотим перенаправить его обратно на страницу входа.

Вот пример реализации компонента частного маршрута, который гарантирует, что пользователь аутентифицирован, чтобы показать ему, что конкретный маршрут был объявлен с этим компонентом.

В противном случае, если они не прошли аутентификацию, они будут перенаправлены на общедоступный маршрут (предположительно, путь для входа в систему) после отображения компонента перенаправления:

import {
  BrowserRouter as Router,
  Switch,
  Route,
  Redirect
} from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Switch>
        <Route exact path="/" component={Home} />
        <PrivateRoute path="/hidden" component={Hidden} />
      </Switch>
    </Router>
  );
}

function PrivateRoute({ component: Component, ...rest }) {
  // useAuth is some custom hook to get the current user's auth state
  const isAuth = useAuth();

  return (
    <Route
      {...rest}
      render={(props) =>
        isAuth ? <Component {...props} /> : <Redirect to="/" />
      }
    />
  );
}

function Home() {
  return <>home</>;
}

function Hidden() {
  return <>hidden</>;
}

Компонент перенаправления очень прост в использовании, очень декларативен и позволяет нам увидеть большое преимущество React Router DOM, основанного на компонентах, как и все в React.

useHistory Hook

Помимо всех этих мощных компонентов, у нас есть несколько очень полезных ловушек, которые дает нам модель React Router DOM.

В основном они полезны тем, что предоставляют дополнительную информацию, которую мы можем использовать в наших компонентах. Их можно назвать обычными хуками React, для которых мы можем использовать их значения так, как нам нравится.

Пожалуй, самый мощный крючок - это крючок 31_. Мы можем вызвать его в верхней части любого компонента, который объявлен в нашем компоненте маршрутизатора, и получить обратно history данные, которые включают такую ​​информацию, как местоположение, связанное с нашим компонентом.

Это говорит нам всем о том, где в настоящее время находится пользователь, например, о пути, по которому он находится, а также о любых параметрах запроса, которые могут быть добавлены к нашему URL-адресу. Все данные о местоположении доступны из history.location:

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


function About() {
  const history = useHistory();
    
  console.log(history.location.pathname); // '/about'

  return (
    <>
     <h1>The about page is on: {history.location.pathname}</h1>
    </>
  );
}

Кроме того, объект истории напрямую включает полезные методы, которые позволяют программно направлять пользователя на разные страницы в нашем приложении.

Это очень полезно, например, для перенаправления нашего пользователя после входа в систему или в любой ситуации, когда нам нужно перевести пользователя с одной страницы на другую.

Мы можем толкать пользователей с одной страницы на другую, используя history.push. Когда мы используем метод push, нам просто нужно указать путь, по которому мы хотим, чтобы наши пользователи использовали этот метод, чтобы добавить эту новую страницу в стек (так сказать) нашей истории:

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


function About() {
  const history = useHistory();
    
  console.log(history.location.pathname); // '/about'

  return (
    <>
     <h1>The about page is on: {history.location.pathname}</h1>
     <button onClick={() => history.push('/')}>Go to home page</button>
    </>
  );
}

Мы также можем перенаправить наших пользователей с помощью history.replace, который также принимает значение пути, но очищает все в истории после выполнения навигации. Это полезно в ситуациях, когда возвращение к истории больше не требуется, например, после выхода пользователей из системы.

useLocation Hook

Хук useLocation включает в себя всю ту же информацию, что и хук useHistory.

Важно отметить, что если вам нужны как данные о местоположении, так и использование истории для программной навигации пользователя, обязательно используйтеHistory. Однако, если вам нужны только данные о местоположении, все, что вам нужно сделать, это вызвать useLocation или получить обратно все данные о местоположении объекта, которые идентичны данным, предоставленным на history. location:

import { useLocation } from "react-router-dom";


function About() {
  const location = useLocation();
    
  console.log(location.pathname); // '/about'

  return (
    <>
     <h1>The about page is on: {location.pathname}</h1>
    </>
  );
}

useParams Hook + Динамические маршруты

Когда дело доходит до маршрутов, мы не учли то, что мы можем естественным образом создавать динамические маршруты, то есть маршруты, которые не являются фиксированными и определенными, но могут содержать любое количество символов.

Динамические маршруты полезны в ситуациях, когда у нас есть, скажем, сообщение в блоге с уникальным слагом. Как убедиться, что мы отображаем соответствующие данные и соответствующие компоненты, учитывая, что наш ярлык сообщения в блоге может быть совершенно другим?

Чтобы объявить параметр маршрута на данном маршруте, он должен быть предварен двоеточием :. Если бы я хотел создать динамический маршрут '/ blog /: postSlug' для компонента сообщения в блоге, он мог бы выглядеть следующим образом:

import React from "react";
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/blog/:postSlug" component={BlogPost} />
      </Switch>
    </Router>
  );
}

function Home() {
  return <>home</>;
}

function BlogPost() {
  return <>blog post</>;
}

Теперь мы сопоставляем соответствующий компонент или что-то еще, что это за ярлык, но как мы можем получить данные этого ярлыка в нашем компоненте BlogPost?

Мы можем получить доступ к любым параметрам маршрута объявленного маршрута с связанным с ним компонентом, используя хук useParams.

useParams вернет объект, который будет содержать свойства, соответствующие нашим параметрам маршрута (в данном случае postSlug). Мы можем использовать деструктуризацию объекта для немедленного доступа и объявления переменной с именем postSlug:

import React from "react";
import { BrowserRouter as Router, Switch, Route, useParams } from "react-router-dom";

export default function App() {
  return (
    <Router>
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/blog/:postSlug" component={BlogPost} />
      </Switch>
    </Router>
  );
}

function Home() {
  return <>home</>;
}

function BlogPost() {
  const [post, setPost] = React.useState(null);
  const { postSlug } = useParams();

  React.useEffect(() => {
    fetch(`https://jsonplaceholder.typicode.com/posts/${postSlug}`)
      .then((res) => res.json())
      .then((data) => setPost(data));
  }, [postSlug]);

  if (!post) return null;

  return (
    <>
      <h1>{post.title}</h1>
      <p>{post.description}</p>
    </>
  );
}

Если мы перейдем к маршруту «/ blog / my-blog-post», я могу получить доступ к строке «my-blog-post» в переменной postSlug и получить данные, связанные с этим сообщением, в useEffect.

useRouteMatch Hook

Если мы хотим знать, находится ли данный компонент на определенной странице, мы можем использовать ловушку useRouteMatch.

Например, в нашем сообщении в блоге, чтобы увидеть, что страница, на которой мы находимся, соответствует маршруту «/ blog /: postSlug», можно вернуть логическое значение, которое сообщит нам, соответствует ли маршрут, по которому мы находимся, шаблону, который мы указано:

import { useRouteMatch } from "react-router-dom";

function BlogPost() {
  const isBlogPostRoute = useRouteMatch("/blog/:postSlug");
 
  // display, hide content, or do something else
}

Это полезно в условиях, когда мы хотим показать что-то конкретное, в зависимости от того, находимся мы на определенном маршруте или нет.

Хотите сохранить это руководство для использования в будущем?

Щелкните здесь, чтобы загрузить шпаргалку в виде полезного PDF-файла.

Вот 3 быстрых победы, которые вы получите, скачав загружаемую версию:

  • Вы получите множество копируемых фрагментов кода, которые можно будет легко повторно использовать в своих проектах.
  • Это отличное справочное руководство, которое поможет вам укрепить свои навыки разработчика на React и пройти собеседование.
  • Вы можете взять, использовать, распечатать, прочитать и перечитать это руководство буквально в любом месте, где захотите.