Перейти к содержимому

React router dom v5 как установить

  • автор:

React Router v5

Today, we are excited to announce the release of React Router version 5. You can get it using:

$ npm install react-router
# or
$ npm install react-router-dom
# or
$ npm install react-router-native

tl;dr

  • React Router version 5 is now available
  • v5 is fully backwards compatible with 4.x
    • The only reason for the major version bump has to do with how we were specifying dependencies in react-router-dom
    • Better support for React 16
    • Eliminates all warnings in
    • New context API (internal only)
    • Fully automated releases

    Structural Improvements

    This release is light on features and fixes, and is more focused on stability and compatibility and preparing the library for future releases.

    There are no breaking changes in this release. If you are already using version 4.x, you can use version 5 immediately with zero code changes. �� Version 5 will pick up where the 4.x roadmap (now the 5.x roadmap) left off.

    The most significant improvement in v5 is better allaround support for React 16, while maintaining full compatibility with React >= 15. We know that a lot of React Router users are maintaing apps they've built over the last few years using various versions of React 15 or 16 and React Router 4, and we are showing our committment to you with this release. This includes upgrading from using React's legacy context API, as well as eliminating all other warnings. My sincere thanks to Tim Dorr for getting the ball rolling here, and my good friend Jared Palmer for prodding me along.

    Using the new context API in React 16 (we use Jamie Kyle's create-react-context shim for backwards compat with React 15) also allows us to avoid the "update blocking" problem that you may have had to work around in the past.

    Side note: we have been working on this problem for over 2 years now . good to see it finally fixed! ��

    Other housekeeping items in this release include a complete overhaul to our bundling infrastructure and full test coverage for all bundles we publish. Before this release we were only running tests on our source code, so there was a chance that our build introduced a bug somewhere. But now all our builds pass all our tests.

    We switched from publishing multiple files for each build to a single file in v5, just like React itself (we copied their code! ��). We also introduced pre-optimized builds for production, so you don't have to manually set process.env.NODE_ENV to production in your build script if you don't want to (though you probably still want to, for other stuff). The point is, you won't be building the router as part of your build. We've already taken care of that, in both development and production modes.

    Probably the most significant change here is that instead of requiring individual files from the router, you need to destructure your imports from the main bundle.

    // Instead of:
    import Router from 'react-router/Router'
    import Switch from 'react-router/Switch'
    // do:
    import Router, Switch > from 'react-router'

    The former style is still supported but will issue a warning in development.

    In addition to these improvements, we did some work to streamline and automate the release process, so we should be able to release more frequently and predictably from now on.

    New Features

    // Instead of this:
    Switch>
    Route path="/users/:id" component=User> />
    Route path="/profile/:id" component=User> />
    /Switch>
    // you can now do this:
    Route path=["/users/:id", "/profile/:id"]> component=User> />

    There are also a few fixes in this release, including support for React.createRef in and support for using React.forwardRef in .

    Why the major version bump?

    We originally intended to release React Router version 5 as 4.4, which we actually did last Friday. However, there was one major consequence which we didn't foresee, and it all boils down to a single character: ^ .

    We have always tried to do versioning as closely as possible to the way the React team does versioning for their packages. In version 4, we have been releasing all react-router* packages in lock step. This means that when you install e.g. react-router-dom version 4.3.0, it depends on react-router version 4.3.0. This makes it easy for people to know which version of each package they need, and is the same as react-dom and react do.

    However, there's one subtle difference between react-router-dom and react-dom , which is that react-router-dom includes react-router as a dependency, not a peer dependency. So in react-router-dom version 4.3.1 we have a dependency on "react-router": "^4.3.1" (note the ^ ).

    At the time we released version 4.4 of both packages on Friday, we had been beta testing 4.4 for over 5 months. We had received tons of feedback over the course of 8 separate beta releases and squashed quite a few bugs, so we felt pretty confident that everything was ready for 4.4 final. But there was one case that we hadn't considered, which is that technically react-router-dom version 4.3.x could depend on react-router version 4.4, which they can't because of the changes to how we're using our internal context API. So although there were no public API breakages between 4.3.x and 4.4.0, there was a chance that some people could install 2 mismatched versions. What made this even trickier is that nobody noticed this bug until 4.4 was out of beta, because there was no chance you'd get a 4.4 beta installed alonside react-router-dom 4.3.x.

    In the end, we decided that the fix that would cause the least pain for everyone would be to npm unpublish version 4.4.0 and re-release it as 5.0.0. This means that:

    • Anyone using version 4.3.x will not get the version mismatch and
    • people who want the new stable version (5.0.0) are still able to get it.

    We apologize for any pain this caused. To fix this problem going forward, we are pinning the react-router dependency in each version of react-router-dom so there is no chance of a version mismatch. We may have a better solution for this in the future, but that's the safest thing for now.

    Thanks

    This release was made possible by many contributors including Tim Dorr, Paul Sherman, Bogdan Chadkin, Dan Levy, Brandon John Lewis, Benjamin Atkin, Hongbo Miao, Ches Zhuravsky, Benjamin Johnson, Daniel Powell, Vernon de Goede, Sebastian Silbermann, Mateusz Burzyński, Ben Mason, Kevin Vicrey, Anthony Frehner, Saugat Acharya, Rick Hanlon II, Eugene Dzhumak, Tien Pham, Peter Fu, alireza-mh, gcangussu, JBallin, misacorn, and many others who contributed code, wrote documentation, or helped us during the beta testing phase.

    I'm sure I missed a few names, so if you helped out and I missed you, please let me know!

    Instead of having comments here in our blog, we've tweeted about this post so you can comment there if you wish.

    react-router-dom

    Then with a module bundler like webpack, use as you would anything else:

    // using ES6 modules
    import BrowserRouter, Route, Link > from "react-router-dom";
    // using CommonJS modules
    const BrowserRouter = require("react-router-dom").BrowserRouter;
    const Route = require("react-router-dom").Route;
    const Link = require("react-router-dom").Link;

    The UMD build is also available on unpkg:

    script src="https://unpkg.com/react-router-dom/umd/react-router-dom.min.js">/script>

    You can find the library on window.ReactRouterDOM .

    If you find a bug, please file an issue on our issue tracker on GitHub.

    React Router is built and maintained by React Training.

    React router dom v5 как установить

    Маршруты могут принимать параметры. Параметр имеет следующую форму определения: :название_параметра .

    Например, используем параметры:

        Маршруты в React           

    Для получения параметров маршрута применяется встроенная функция-хук useParams , соответственно ее вначале необходимо получить:

    const useParams = ReactRouterDOM.useParams;

    Здесь определен один маршрут, который принимает параметр:

    Причем он определен как дочерний по отношению к маршруту "/products". То есть к подобному ресурсу нам надо будет обращаться по адресу, к примеру

    http://localhost:3000/products/5

    где 5 - значение для параметра id. Этот маршрут будет обрабатываться компонентом Product. Причем надо учитывать, что хуки могут применяться только в функциональных компонентах. Поэтому компонент Product определен в виде функции:

    function Product()< // получаем параметры const params = useParams(); const prodId = params.id; return Товар № ; >

    Функция useParams() возвращает набор параметров маршрута. Фактически такой набор представляет объект, а каждый отдельный параметр - свойство этого объекта. И чтобы получить параметр id, необходимо использовать выражение params.id .

    Если же параметр не будет передан, например, при запросе http://localhost:3000/products , то он будет обрабатываться компонентом ProductsList.

    И в зависимости от наличия параметра мы получим тот или иной результат:

    Параметры маршрутов в React Передача параметров в React

    Стоит отметить, что поскольку функции-хуки, типа useParams, можно использовать только в функциональных компонентах, то напрямую использовать в компонентах=классах мы ее не можем. И при использовании компонентов-классов одно из распространенных решений состоит в том, чтобы компонент, который использует useParams() , сделать функциональным:

        Маршруты в React           

    Подобным образом мы можем использовать и большее количество параметров. Например, изменим компонент Product и его маршрут:

    const Router = ReactRouterDOM.BrowserRouter; const Route = ReactRouterDOM.Route; const Routes = ReactRouterDOM.Routes; const useParams = ReactRouterDOM.useParams; const Outlet = ReactRouterDOM.Outlet; function ProductsList()< return 

    Список товаров

    ;> function Product()< // получаем параметры const params = useParams(); const prodId = params.id; const prodName = params.name; return

    Id: Name: ; > function Products() < return (

    Товары

    ); > ReactDOM.createRoot( document.getElementById("app") ) .render(
    Главная

    > /> >> > /> > /> Ресурс не найден> />
);

Теперь компонент Product получает два параметра - id и name:

Параметры в маршрутах в React

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

    Маршруты в React           

Параметры в маршрутах в React-Router-Dom

В то же время маршруту по пути "/products/:id/:cat" обязательно надо передать два параметра, если мы передадим в запросе только один параметр, то данный запрос будет обрабатываться последним маршрутом.

Подробно о React Router. Часть 1 — основы роутинга, типы и динамические страницы

# react# react router

Стас Багрецов

11 июня 2020 г.

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

p.s статья описывает самый распространенную версию роутера на данный момент. 6я версия сейчас находится в альфе и имеет кардинально другой синтаксис.

React это широко используемая библиотека для client-side веб приложений. Сами знаете, в любом веб приложении будет по несколько страниц. Правильный роутинг ссылок и загрузка разных страниц в зависимости от параметров заданных маршрутов это главное требование для буквально любого приложения.

Существует отличный npm пакет, который берет на себя все сложности роутинга на React. Это react-router-dom — одна из самых используемых библиотек в react.

Простой роутинг

Давайте создадим две простые страницы.

И страницу About ( /about )

Создайте простое react приложение с использованием create-react-app CLI. Это очень просто сделать с помощью npx — npx create-react-app my-react-app

// App.js import React from 'react'; const App = () =>  return ( section className="App"> h1>React routing Example/h1> /section> ); >; export default App;

Давайте создадим две страницы. Ну или просто два функциональных компонента.

// App.js . const IndexPage = () =>  return ( h3>Home Page/h3> ); >; const AboutPage = () =>  return ( h3>About Page/h3> ); >; . 

Перед тем как углубиться в код роутера. Давайте сначала поймем то, что же нам надо для роутинга страниц в нашем приложении.

Ссылки для навигации между страницами.

Нам нужно будет определить пути к страницам. Тут мы укажем путь URL и компонент, который нужно загружать с этим URL.

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

Итак, давайте создадим компоненты Link и Route . Для начала установите пакет yarn add react-router-dom .

// App.js . import  Link, BrowserRouter as Router, Route > from 'react-router-dom';. const App = () =>  return ( section className="App"> Router> Link to="/">Home/Link> Link to="/about">About/Link> Route path="/" component=IndexPage> /> Route path="/about" component=AboutPage> /> /Router> /section> ); >;

А теперь дайте пройдем по каждой строчке отдельно.

import  Link, BrowserRouter as Router, Route > from 'react-router-dom';

Тут мы импортируем три компонента,

Link , который создаст HTML ссылку на страницы.

Route , который укажет маршруты.

И Router в котором будет храниться вся логика нашего роутинга. Когда пользователь кликает на ссылку, этот компонент проверяет есть ли она в указанных роутах. Если да, то роутер сменит URL в браузере и роут отрендерит заданный компонент.

// Link with URL Router> Link to="/">Home/Link> Link to="/about">About/Link> /Router>

Router должен быть родительским компонентом для Link и Route . Собственно так он и управляет роутингом. Если мы поставим Link или Route за его пределы, то тут мы получим ошибку.

Зачем нам нужен Link, а не HTML анкор с href?

HTML тег a создает ссылку на сервер. Так что каждый раз, как пользователь кликает на роут, он не будет проверять наличие роутера в роуте. Вместо этого он просто редиректнет страницу в браузере на этот роут.

В то время как Link проверяет роутер и роутер проверяет наличие роута, загружая компонент без перезагрузки страницы. Поэтому это и называется client side роутингом. Он не подгружает страницу с сервера при обращении к компоненту Link .

// Route with definition Route path="/" component=IndexPage> />

Тут у Route есть путь и props компоненты. component помогает отрендерить компонент, когда пользователь заходит на этот роут. path props указывает путь url , который должен совпадать при посещении пользователем страницы.

Если вы зайдете немного дальше и проверите работу наших роутов, то они будут работать. Но с небольшими тормозами.

Кликнув на ссылку about , она отрендерит и IndexPage , и AboutPage . Но почему?

Потому что путь указанный для About это /about . Роутер же в свою очередь пробегается по всем определением роутов, сверху вниз. Сначала он проверяет роут с путем / , а у About в URL есть / , так что сначала он рендерит IndexPage . А уже потом проверяет следующий роут /about , который тоже совпадает с заданными параметрами, что приводит к рендерингу компонента AboutPage .

Как точно попасть на нужный роут?

Всё очень просто. Используйте props exact в Route .

. const App = () =>  return ( section className="App"> Router> Link to="/">Home/Link> Link to="/about">About/Link> Route exact path="/" component=IndexPage> /> Route exact path="/about" component=AboutPage> /> /Router> /section> ); >; . 

Этот prop поможет попасть на нужный роут только при полном совпадении, а если нет, то он просто не будет рендерить компонент.

Теперь оба компонента будут отлично рендериться и Link будет работать правильно.

Какие бывают роутеры

В предыдущей секции обсуждали самые основы роутинга в React. Там мы использовали BrowserRouter , как основной роутер.

Но есть ещё несколько других типов роутеров в react router . Сейчас мы посмотрим когда их использовать.

MemoryRouter

// https://example.com (Один и тот же url для всех роутов) import  MemoryRouter as Router > from ‘react-router-dom’;

Это роутер, который не меняет URL в браузере, а оставляет изменения в памяти.

Он очень полезен для тестирования и вне браузерных сред разработки.

Но в браузере у него нет истории. Так что вы не сможете вернуться назад или вперед при помощи истории.

HashRouter

/* Роуты с хешем, тут вы можете обращаться к истории. https://example.com/#/ https://example.com/#/about */ import  HashRouter as Router > from 'react-router-dom';

Это роутер, который использует client Side hash роутинг.

Всякий раз, когда рендерится новый роут, он обновляет URL в браузере с хешированными роутами. (/#/about)

Хэш часть ссылки не будет обработана сервером, сервер будет всегда отправлять index.html для каждого запроса и игнорировать хешированное значение, которое будет обработано уже React роутером.

Он используется для Legacy браузеров, которые обычно не поддерживают pushState API.

Ему не нужна конфигурация на сервере для обработки роутов.

Этот роут не рекомендован командой разработчиков которая создавала сам пакет react router. Используйте его только в том случае, если вам нужна поддержка Legacy браузеров или при осутствии серверной логики для обработки client Side роутов.

BrowserRouter

/* Вы можете использовать историю https://example.com/ https://example.com/about */ import  BrowserRouter as Router > from 'react-router-dom';

Самый популярный роутер и роутер для современных браузеров, который использует HTML5 pushState ( pushState , replaceState и popState API)

Он роутится как обычный URL в браузере, так что вы не сможете по ссылке отличить был ли это server Side рендеринг или же client side.

Тут подразумевается то, что ваш сервер обрабатывает все URL запросы ( / , /about ) и указывает на корневой index.html . И уже отсюда, BrowserRouter обрабатывает роутинг релевантной страницы.

Он принимает forceRefresh пропсы для поддержки Legacy браузеров, которые не тянут HTML5 pushState API.

Динамические страницы в React Router

В начале статьи мы изучили то, как создавать простые статические страницы в роутере. Сейчас мы узнаем как создавать динамические ссылки в react роутере.

Мы создадим два роута,

Роут Users — статические роуты для отображения всех ссылок для отдельных пользователей.

Роут User — каждый пользователь будет идентифицирован по своему уникальному ID и ссылка будет передавать этот ID , а компонент будет отображать нужный контент пользователя.

Давайте создадим простой массив users с данными пользователей.

const users = [   name: `Param`, >,   name: `Vennila`, >,   name: `Afrin`, >, ];

Давайте создадим новые роуты для всех пользователей и одного пользователя в нашем App.js файле.

// App.js . const UsersPage = () =>  return ( h3>Users Page/h3> );>; const App = () =>  return ( section className="App"> Router> Link to="/">Home/Link> Link to="/about">About/Link> Link to="/users">Users/Link> Route exact path="/" component=IndexPage> /> Route exact path="/users" component=UsersPage> /> Route exact path="/about" component=AboutPage> /> /Router> a href="/about">about with browser reload/a> /section> ); >; . 

Мы создали ссылку на страницу пользователей и также определили роут для страницы пользователей вместе с ассоциированным компонентом ( UsersPage ).

Давайте создадим ссылки для каждого из них с UsersPage . ( /user/1 , /user/2 , /user/3 )

// userId будет индекс в массиве + 1 const UsersPage = () =>  return ( > h3>Users Page/h3> users.map((user, index) => ( h5 key=index>> Link to=`/user/$index + 1>`>>user.name>'s Page/Link> /h5> ))> /> ); >;

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

Мы можем создать каждый отдельный роут как тут:

Route exact path="/user/1" component=UserPage1> /> Route exact path="/user/2" component=UserPage2> />

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

Route path="/user/:userId" component=UserPage> /> 

Тут :userId это динамические параметры роута. Он передается компоненту. Вы легко можете получить доступ к пропсам userId в компоненте UserPage .

Давайте добавим этот код в наш пример.

// App.js . const UserPage = () =>  return ( h3>User Page/h3> );>; const App = () =>  return ( section className="App"> Router> Link to="/">Home/Link> Link to="/about">About/Link> Link to="/users">Users/Link> Route exact path="/" component=IndexPage> /> Route exact path="/users" component=UsersPage> /> Route exact path="/user/:userId" component=UserPage> /> Route exact path="/about" component=AboutPage> /> /Router> a href="/about">about with browser reload/a> /section> ); >; . 

Теперь наша страница пользователя работает. Но она не показывает никакую информацию непосредственно о самом пользователе. Давайте с этим разберемся.

Как получить доступ к параметрам роута в компоненте

React роутер передаёт два пропса всем компонентам. Это match и location .

Давайте посмотрим, какая информация находится в этих пропсах, выведя их через сам компонент.

// App.js const UserPage = ( match, location >) =>  return ( > p> strong>Match Props: /strong> code>JSON.stringify(match, null, 2)>/code> /p> p> strong>Location Props: /strong> code>JSON.stringify(location, null, 2)>/code> /p> /> ); >;

И что же там внутри:

/* URL: /user/1 userId: 1 */ // Match Props < "path": "/user/:userId", "url": "/user/1", "isExact": true, "params": < "userId": "1" >> // Location Props < "pathname": "/user/1", "search": "", "hash": "", "key": "7e6lx5" >

Если мы взглянем на контент, то интересный нам параметр userId находится в match.params.userId .

Давайте применим параметры в UserPage компоненте и покажем информацию о пользователе:

// Получаем userId из пропса match и показываем конкретного пользователя из массива пользователей const UserPage = ( match, location >) =>  const  params:  userId > > = match; return ( > p> strong>User ID: /strong> userId> /p> p> strong>User Name: /strong> users[userId - 1].name> /p> /> ); >;
// Деструктуризация объекта in JavaScript const   params:  userId >, > = match;

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *