React Router DOM v5¶
Внимание
Это перевод документации по React Router v5.x
Перевод шестой версии здесь — React Router v6
Примеры¶
Основная маршрутизация¶
В приведенном ниже примере у нас имеется 3 страницы, обрабатываемые роутером: главная (home), контакты (about) и страница с пользователями (users). При клике по <Link>
(ссылке) роутер рендерит соответствующий <Route>
(маршрут, путь).
Обратите внимание: за сценой <Link>
рендерит <a>
с настоящим href
, так что люди, использующие клавиатуру для навигации или экранные считываюющие устройства (screen readers), смогут без проблем пользоваться приложением.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
|
Вложенный роутинг¶
Ниже приводится пример вложенного роутинга. Маршрут /topics
загружает компонент Topics
, который, в свою очередь, рендерит дальнейшие <Route>
на основе значения :id
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
|
Основные компоненты¶
В React Router
существует 3 категории компонентов:
- роутеры (routers), например,
<BrowserRouter>
или<HashRouter>
- маршруты (route matchers), например,
<Route>
или<Switch>
- и навигация (navigation), например,
<Link>
,<NavLink>
или<Redirect>
Все компоненты, используемые в веб-приложении, должны быть импортированы из react-router-dom
.
Роутеры¶
Любая маршрутизация начинается с роутера. Для веб-проектов react-router-dom
предоставляет <BrowserRouter>
и <HashRouter>
. Основное отличие между ними состоит в способе хранения URL и взаимодействия с сервером.
<BrowserRouter>
использует обычные URL. В этом случае URL выглядят как обычно, но требуется определенная настройка сервера. В частности, сервер должен обслуживать все страницы, используемые на клиенте.Create React App
поддерживает это из коробки в режиме разработки и содержит инструкции для правильной настройки сервера.<HashRouter>
хранить текущую локацию в хэш-части URL (после символа "#"), поэтому URL выглядит примерно так:http://example.com/#/your/page
. Поскольку хэш не отправляется серверу, его специальная настройка не требуется.
Для использования роутера необходимо обернуть в него компонент верхнего уровня:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Маршруты¶
Существует 2 вида компонентов для поиска совпадений с URL: Switch
и Route
. При рендеринге <Switch>
определяет <Route>
, соответствующий текущему URL. При обнаружении такого маршрута, он рендерится, остальные маршруты игнорируются. Это означает, что вы должны помещать более специфические маршруты перед менее специфическими.
Если совпадения не найдено, <Switch>
ничего не рендерит (точнее, рендерит null
).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
|
Обратите внимание, что <Route path>
ищет совпадение с началом, а не со всем URL. Поэтому <Route path="/">
всегда будет совпадать с URL. Поэтому в <Switch>
мы, обычно, помещаем его последним. Другим возможным решением является использование атрибута exact
: <Route exact path="/">
, который заставляет роутер искать полное совпадение.
Навигация¶
React Router
предоставляет компонент <Link>
для создания ссылок в приложении. При использовании <Link>
в HTML рендерится <a>
.
1 2 |
|
<NavLink>
- это специальный тип <Link>
, позволяющий определять стили для активного состояния ссылки.
1 2 3 4 5 6 7 8 9 |
|
Для принудительной навигации используется <Redirect>
. При рендеринге <Redirect>
выполняется перенаправление.
1 |
|
API¶
Хуки¶
React Router
предоставляет несколько хуков для доступа к состоянию роутера и навигации внутри компонентов.
Указанные хуки предоставляют доступ к следующим объектам:
history
location
match
matchPath
useHistory¶
Данный хук предоставляет доступ к экземпляру истории (history instance), который может использоваться для навигации:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
history¶
Термины "история" (history) и "объект истории" (history object) являются ссылками на пакет history, одну из двух зависимостей React Router
(вторая - сам React
), представляющий собой несколько реализаций, позволяющих управлять историей сессии с помощью JavaScript
в разных окружениях.
Объекты истории, как правило, имеют следующие свойства и методы:
length
number
- количество вхождений в стеке истории (history stack)action
string
- текущая операция (PUSH
,REPLACE
илиPOP
)location
object
- текущая локация. Может иметь следующие свойства:
pathname
: string - адрес URLsearch
: string - строка запроса URLhash
: string - хэш-фрагмент URLstate
: object - специфичное для локации состояние, переданное, например, с помощьюpush(path, state)
при помещении локации в стек. Доступно только в браузере и истории, хранящейся в памяти
push(path, [state])
func
- помещает новое вхождение в стек историиreplace(path, [state])
func
- заменяет текущее вхождение в стеке историиgo(n)
func
- перемещает указатель в стеке истории на n вхожденийgoBack()
func
- эквивалент go(-1)goForward()
func
- эквивалент go(1)block(prompt)
func
- запрещает переход на другую страницу
useLocation¶
Данный хук возвращает объект локации (location object), содержащий информацию о текущем URL. Вы можете думать о нем как о useState
, возвращающем новую локацию при изменении URL.
Это может быть полезным в ситуации, когда необходимо получить новое представление страницы с помощью инструмента веб-аналитики при загрузке новой страницы, как в следующем примере:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
location¶
Объект локации выглядит следующим образом:
1 2 3 4 5 6 7 8 9 |
|
Объект локации доступен в:
- Компоненте
Route
какthis.props.location
(props.location
) - Пропе
render
компонентаRoute
как({ location }) => ()
- Потомках (
children
) компонентаRoute
как({ location }) => ()
withRouter
какthis.props.location
Он также доступен в history.location
.
Объект локации, в отличие от объекта истории, никогда не мутирует, поэтому его можно использовать для определения того, выполнялась ли навигация, например, для получения данных и запуска анимации.
Вы можете использовать location
для навигации вместо строк в:
Link to
для вебаLink to
для React NativeRedirect to
history.push
history.replace
Обычно, во всех перечисленных случаях мы используем строку, однако, когда необходимо добавить некоторое "состояние локации", которое будет доступным при возвращении приложения в данную локацию, можно использовать объект локации. Это может пригодиться в случае, когда определенные части интерфейса зависят от истории навигации, а не от путей (например, модульные окна).
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Наконец, location
можно передавать в следующие компоненты:
Route
Switch
Это предотвратит использование ими актуальной локации из состоянии роутера. Это может быть полезным для анимации и отложенной навигации, а также для замены локации, в которой рендерится компонент.
useParams¶
Данный хук возвращает объект с параметрами URL в формате ключ: значение
. Используется для доступа к match.params
текущего <Route>
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
useRouteMatch¶
Данный хук пытается найти совпадение для текущего URL подобно <Route>
. Он может быть полезен для доступа к совпадающим данным без рендеринга <Route>
.
Это позволяет вместо
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
делать так
1 2 3 4 5 6 7 8 |
|
useRouteMatch
:
- без аргументов: возвращает объект совпадения текущего
<Route>
- принимает один аргумент, эквивалентный пропу
matchPath.argument
. Это может бытьpathname
в виде строки, как в приведенном выше примере, или объект с пропами, принимаемыми<Route>
, как в следующем примере:
1 2 3 4 5 |
|
match¶
Объект совпадения (match object) содержит информацию о том, насколько <Route path>
совпадает с URL. Он имеет следующие свойства:
params
object
- пары ключ/значение, соответствующие динамической части URLisExact
bool
-true
, если имеет место совпадениеpath
string
- паттерн пути, используемый для поиска совпадения. Используется для построения вложенных<Route>
url
string
- совпавшая часть URL. Используется для создания вложенных<Link>
Доступ к объекту совпадения можно получить в:
Route
какthis.props.match
(props.match
)- Пропе
render
компонентаRoute
как({ match }) => ()
- Потомках
Route
как({ match }) => ()
withRouter
какthis.props.match
matchPath
в виде возвращаемого значенияuseRouteMatch
в виде возвращаемого значения
Если Route
не имеет пропа path
и поэтому всегда совпадает, мы получаем его ближайшего предка. Тоже самое справделиво для withRouter
.
Совпадение с null
<Route>
, имеющий проп children
, вызывает функцию данного пропа даже при отсутствии совпадения с текущей локацией. В этой ситуации match
будет иметь значение null
. Может быть полезным иметь возможность рендерить контент <Route>
при совпадении, но на этом пути существует несколько препятствий.
Обычный способ "разрешения" URL заключается в объединении строки match.url
и "относительного" пути.
1 |
|
Если вы попытаетесь это сделать при нулевом совпадении, будет выброшено исключение TypeError
. Это означает, что объединение "относительных" путей внутри <Route>
, использующего для этого проп children
, является небезопасным.
Похожая ситуация возникает при использовании <Route>
без path
внутри <Route>
, генерирующего нулевой объект совпадения.
1 2 3 4 5 6 7 8 9 10 11 |
|
<Route>
без path
наследует объект совпадения от предка. Если match
предка равняется null
, то его match
также будет иметь значение null
. Это означает, что, во-первых, любой дочерний маршрут/ссылка будут абсолютными (отсутствует предок для разрешения пути), во-вторых, маршрут без пути, родительский match
которого может иметь значение null
, должен будет использовать проп children
для рендеринга.
matchPath¶
Позволяет использовать такой же код, что и <Route>
, но за пределами нормального цикла рендеринга, например, на сервере для сбора информации об используемых данных перед рендерингом.
1 2 3 4 5 6 7 |
|
Принимает следующие аргументы:
pathname
string
- название пути для поиска совпадения.req.path
на сервереprops
- пропы для поиска совпадения; соответствуют пропам, принимаемым
<Route>
1 2 3 4 5 |
|
При совпадении возвращается такой объект:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
В противном случае, возвращается null
.
<Router>
¶
Общий низкоуровневый интерфейс для компонентов роутера. Обычно, используется один из следующих роутеров:
<BrowserRouter>
<HashRouter>
<MemoryRouter>
<StaticRouter>
<NativeRouter>
Одним из случаев использования низкоуровневого <Router>
является синхронизация пользовательской истории с такими библиотеками для управления состоянием приложения, как Redux
или MobX
. Обратите внимание, что делать этого не рекомендуется.
Пропcы:
history
object
- атрибут, используемый для навигацииchildren
node
- дочерний элемент
<BrowserRouter>
¶
<Router>
, использующий HTML5 history API
(события "pushState", "replaceState" и "popState") для синхронизации UI с URL.
1 2 3 4 5 6 7 8 |
|
Пропcы:
basename
string
- базовый URL для всех локаций. Если приложение обслуживается из поддиректории на сервере, базовый URL должен иметь значение данной поддиректории
1 2 3 4 5 |
|
getUserConfirmation
func
- функция для подтверждения перехода на другую страницу (по умолчанию используетсяwindow.confirm
)
1 2 3 4 5 6 7 |
|
forceRefresh
bool
- еслиtrue
, выполняется полное обновление страницы. Используется для имитации поведения сервера при переключении страницkeyLength
number
- длинаlocation.key
(по умолчанию равняется 6)children
node
- дочерние элементы
<HashRouter>
¶
<Router>
, использующий хэш-часть URL (т.е. window.location.hash
) для синхронизации UI с URL.
Обратите внимание, что хэш-история не поддерживает location.key
или location.state
.
1 2 3 4 5 6 7 |
|
Пропcы:
basename
string
- базовый URL для всех локаций
1 2 |
|
getUserConfirmation
func
- функция для подтверждения перехода на другую страницу (по умолчанию используетсяwindow.confirm
)hashType
string
- тип кодировки дляwindow.location.hash
.
Доступные значения:
slash
-#/
и#/sunshine/lollipops
(значение по умолчанию)noslash
-#
и#sunshine/lollipops
hashbang
-#!/
и#!/sunshine/lollipops
(признан устаревшим в Chrome)
children
node
- дочерний элемент
<MemoryRouter>
¶
<Router>
, хранящий историю URL в памяти (не читает и не пишет в адресную строку). Используется для тестирования и вне браузера (например, в React Native
).
1 2 3 4 5 6 7 8 |
|
Пропcы:
initialEntries
array
- массив локаций в стеке истории. Локации могут быть полноценными объектами с{ pathname, search, hash, state }
или строками
1 2 3 4 5 6 7 8 9 10 |
|
initialIndex
number
- индекс начальной локации в массивеinitialEntries
getUserConfirmation
func
- функция для подтверждения перехода на другую страницу (по умолчанию используетсяwindow.confirm
)keyLength
number
- длинаlocation.key
(по умолчанию - 6)children
node
- дочерние элементы
<StaticRouter>
¶
<Router>
, не изменяющий локацию. Используется в сценариях рендеринга на стороне сервера и для тестирования результатов рендеринга при подключении определенной локации.
Пример node-сервера, отправляющего статус-код 302 для <Redirect>
и обычный HTML в ответ на другие запросы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Пропcы:
basename
string
- базовый URL для всех локацийlocation
string
- URL, принимаемый сервером (req.url
)location
object
- объект локации вида{ pathname, search, hash, state }
context
object
- обычный JS-объект. В процессе рендеринга компоненты могут добавлять свойства к этому объекту для хранения информации о рендеринге
1 2 3 4 |
|
При совпадении, <Route>
передает компоненту, подлежащему рендерингу, объект контекста как проп staticContext
. После рендеринга, эти свойства могут использоваться для настройки ответа сервера:
1 2 3 |
|
children
node
- дочерние элементы
<Link>
¶
<NavLink>
Обеспечивает декларативный и доступный способ навигации в приложении.
1 |
|
Пропcы:
to
string
- строковое представление локации, создаваемое посредством объединения свойствpathname
,search
иhash
1 |
|
to
object
- объект, который может иметь следующие свойства:pathname
string
- название путиsearch
string
- параметры строки запросаhash
string
- хэш-часть URLstate
object
- состояние локации
1 2 3 4 5 6 7 8 |
|
to
func
- функция, которой в качестве аргумента передается текущая локация и которая должна вернуть представление локации в виде строки или объекта
1 2 |
|
replace
bool
- еслиtrue
, тогда новая локация заменяет текущую в стеке истории, а не добавляется к ней
1 |
|
component
React.Component
- для реализации собственного компонента навигации достаточно передать данный проп
1 2 3 4 5 |
|
другие:
title
,id
,className
и т. д.
<NavLink>
¶
Специальная версия <Link>
, предназначенная для добавления стилей к элементу, совпадающему с текущим URL (активному элементу).
1 |
|
Пропcы:
activeClassName
string
- класс активного элемента. Значением по умолчанию являетсяactive
. Объединяется с пропомclassName
1 2 3 |
|
activeStyle
object
- стили, применяемые к активному элементу
1 2 3 4 5 6 7 8 9 |
|
exact
bool
- еслиtrue
, тогда активный класс/стили применяются только при точном совпаденииstrict
bool
- еслиtrue
, тогда при определении совпадения учитывается замыкающий (последний) слэшisActive
func
- дополнительная логика для определения активности ссылки
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
location
object
- используется для сравнения с другой локациейaria-current
string
- значение атрибутаaria-current
активной ссылки. Возможные значения:page
(значение по умолчанию),step
,location
,date
,time
,true
,false
.
<Switch>
¶
Рендерит первый дочерний <Route>
или <Redirect>
при совпадении с текущей локацией (URL).
В чем состоит особенность <Switch>
?
Особенность <Switch>
состоит в том, что он рендерит только один маршрут из набора. Без <Switch>
рендерится каждый маршрут, совпавший с локацией.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
В приведенном примере при значении URL, равном /about
, все 3 компонента будут совпадать с локацией и отрендерятся. Это позволяет выстраивать композицию компонентов ("сайдбары" - sidebars, "хлебные крошки" - breadcrumbs, "табы" - tabs и т.д.).
Тем не менее, обычно, мы хотим рендерить только один <Route>
. Если мы находимся в /about
, то едва ли мы хотим рендерить компонент <User />
или страницу ошибки 404. Вот как добиться этого с помощью <Switch>
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Это также может быть полезным для выполнения анимированных переходов, поскольку новый маршрут рендерится на той же позиции, что и предыдущий.
Пропcы:
location
object
- используется для поиска совпадения вместо текущего объекта локации (текущего браузерного URL)children
node
- потомки<Switch>
должны быть элементами<Route>
или<Redirect>
.<Route>
совпадает по пропуpath
,<Redirect>
- по пропуfrom
. Указанные элементы без соответствующих пропов всегда совпадают. При включении<Redirect>
в<Switch>
, в последнем могут использоваться все пропы<Route>
(path
,exact
иstrict
). Пропfrom
- это синоним пропаpath
. Если в<Switch>
передан пропlocation
, значениеlocation
совпавшего потомка будет перезаписано.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
<Route>
¶
Данный компонент является ключевым в React Router
. Поэтому важно хорошо знать, как он работает. В основном, он отвечает за рендеринг определенного UI при совпадении значения его пропа path
с текущим URL.
Рассмотрим следующий код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Если локацией приложения будет /
, то иерархия UI будет выглядеть так:
1 2 3 4 |
|
А для локации /news
так:
1 2 3 4 |
|
Комментарии "react-empty" - это детали реализации нулевого рендеринга. Технически, маршрут рендерится всегда: при совпадении с текущей локацией рендерится компонент, при несовпадении - null
. Если один и тот же компонент является потомком нескольких <Route>
, React
будет рассматривать его как один и тот же экземпляр и состояние компонента будет автономным, т.е. компонент не будет перерисовываться при изменении локации. Во избежание этого к каждому <Route>
добавляется проп key
с уникальным значением.
Методы рендеринга маршрута¶
Рекомендуемым способом рендеринга является использование дочерних элементов как в приведенном выше примере. Тем не менее, существует и другие способы:
<Route component>
<Route render>
<Route children>
Следует придерживаться одного стиля.
Пропы маршрута¶
Все 3 метода рендеринга принимают следующие пропы:
match
location
history
component¶
Компонент, подлежащий рендерингу при совпадении с локацией. Данному компоненту доступны все пропы маршрута:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
При использовании component
(вместо render
или children
), маршрут использует React.createElement
для создания нового React-элемента. Это означает, что при передаче встроенной функции в качестве пропа компонента, при каждом рендеринге будет создаваться новый компонент. Это приводит к размонтированию/монтированию нового компонента вместо обновления существующего. Поэтому при необходимости передачи встроенной функции следует использовать render
или children
.
render: func¶
Это позволяет реализовать встроенный рендеринг без нежелательного перемонтирования.
Вместо создания нового элемента с помощью пропа component
, можно передать функцию, вызываемую при совпадении с локацией. Данная функция имеет доступ ко всем пропам маршрута:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
|
children: func¶
Порой нам требуется условный рендеринг. В этом случае можно использовать функцию в качестве значения пропа children
. Она работает как render
, за исключением того, что вызывается в зависимости от совпадения с локацией.
Данный проп принимает те же пропы маршрута. При несовпадении маршрута, проп match
будет иметь значение null
. Это позволяет динамически обновлять UI. В приведенном ниже примере мы динамически добавляем класс active
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
Это также может использоваться для анимации:
1 2 3 4 5 6 7 8 9 |
|
Пропcы:
path
string
,string[]
- любой валидный URL или массив таких URL (маршрут безpath
совпадает с любой локацией)
1 2 3 4 5 6 |
|
exact
bool
- еслиtrue
, осуществляется поиск точного совпадения сlocation.pathname
1 2 3 |
|
strict
bool
- еслиtrue
, при поиске совпадения учитывается замыкающий слэшlocation
object
- используется для поиска совпадения с указанной локацией вместо текущейsensitive
bool
- еслиtrue
, при поиске совпадения учитывается регистр
<Redirect>
¶
Рендеринг <Redirect>
приводит к перемещению в новую локацию. Новая локация перезаписывает текущую в стеке истории, как при серверном перенаправлении (HTTP 3xx).
1 2 3 4 5 6 7 |
|
Пропcы:
to
string
- любой валидный URLto
object
- объект локации для перенаправления
1 2 3 4 5 6 7 |
|
В компоненте Login
объект state
доступен через props.location.state
, а ключ referrer
- через props.state.referrer
.
push
bool
- еслиtrue
, новая локация добавляется в стек истории, а не заменяет текущуюfrom
string
- любой валидный URL. Может использоваться только при включении в<Switch>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
exact
bool
- точное совпадение, аналогRoute.exact
. Может использоваться только совместно сfrom
strict
bool
- учет замыкающего слэша, аналогRoute.strict
. Может использоваться только совместно сfrom
sensitive
bool
- учет регистра, аналогRoute.sensitive
<Prompt>
¶
Используется для обращения к пользователю перед переключением страницы. Это может быть полезным для предотвращения преждевременного или случайного переключения страницы пользователем (например, при наполовину заполненной форме).
1 2 3 4 |
|
Пропcы:
message
string
- сообщение, выводимое при попытке пользователя перейти на другую страницуmessage
func
- вызывается со следующей локацией и операцией при попытке пользователя перейти на другую страницу. Возвращает строку - сообщение для пользователя илиtrue
для выполнения перехода
1 2 3 4 5 6 7 8 9 10 11 |
|
when
bool
- вместо условного рендеринга<Prompt>
, можно рендерить его всегда, передаваяwhen={true}
илиwhen={false}
для контроля навигации
generatePath¶
Функция generatePath
может вызываться для генерации URL для маршрутов. В ней используется библиотека path-to-regexp
.
1 2 3 4 5 6 7 |
|
Результаты компиляции путей кэшируются, так что генерация множества путей на основе одного шаблона не приводит к лишнему расходу памяти.
Пропcы:
pattern
string
- шаблон, передаваемый как атрибутpath
в<Route>
params
object
- объект с параметрами для шаблона. При несовпадении параметров и пути, выбрасывается исключение
1 2 3 4 |
|
withRouter¶
С помощью компонента высшего порядка withRouter
можно получить доступ к свойствам объекта history
и match
ближайшего маршрута. withRouter
передает дочернему компоненту обновленные пропы match
, location
и history
при его рендеринге:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Обратите внимание, withRouter
не подписывается на изменение локации подобно подключению React Redux
к изменению состояния. Повторный рендеринг после изменения локации "распространяется" от <Router>
. Это означает, что withRouter
перерисовывается только вслед за родительским компонентом.
Статические методы и свойства (не принадлежащие React) оборачиваемого компонента автоматически копируются в "подключенный" компонент.
Component.WrappedComponent
- оборачиваемый компонент преобразуется в статическое свойствоWrappedComponent
возвращаемого компонента, что, помимо прочего, может использоваться для тестирования компонента в изоляции.
1 2 3 4 5 6 |
|
wrappedComponentRef
: func - функция, передаваемая оборачиваемому компоненту в качестве пропаref
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Рендеринг на стороне сервера¶
Маршрутизация на стороне сервера немного отличается ввиду отсутствия состояния. Основная идея состоит в том, что компонент верхнего уровня оборачивается в <StaticRoute>
вместо <BrowserRoute>
. Затем мы передаем роутеру запрашиваемый URL и контекст.
1 2 3 4 5 6 7 8 9 10 11 12 |
|
При рендеринге <Redirect>
на клиенте, история браузера изменяется, и мы получаем новое представление (видим новый экран). В статическом серверном окружении мы не может менять состояние приложения. Вместо этого, мы используем проп context
для определения результата рендеринга. Если мы обнаруживаем context.url
, значит, имело место перенаправление. Это позволяет выполнять перенаправление на сервере.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Добавление информации о контексте¶
Роутер просто добавляет context.url
. Однако, вам может потребоваться указать код 301 или 302. Или вы хотите отправлять ответ 404 для некоторых частей UI, или 401 при отсутствии авторизации. Проп context
находится в вашем распоряжении, так что вы можете его изменять. Ниже приводится способ указания кодов 301 и 302:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
|
404, 401 или любой другой статус¶
Делаем тоже самое. Создаем компонент, добавляющий контекст, и рендерим его в приложении для получения разных статус-кодов.
1 2 3 4 5 6 7 8 9 |
|
После этого вы можете рендерить Status
где угодно для получения кода для staticContext
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Все вместе¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
1 2 3 4 5 6 7 8 9 10 11 |
|
Загрузка данных¶
Данные должны загружаться перед рендерингом. React Router
предоставляет статическую функцию matchPath
, которая используется для определения маршрута. Вы можете использовать эту функцию на сервере для определения данных, которые потребуются приложению, перед рендерингом.
Суть данного подхода заключается в использовании статических настроек для определения данных по маршруту:
1 2 3 4 5 6 7 |
|
Затем этот конфиг используется для рендеринга маршрутов:
1 2 3 4 5 6 7 8 9 |
|
Сервер:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Наконец, клиент должен каким-либо способом получить данные.
Разделение кода (code splitting)¶
Одной из замечательных возможностей веба является то, что нам не нужно заставлять пользователей загружать все приложение целиком. Вы можете думать о разделении кода как о постепенной загрузке приложения. Для реализации этого мы будем использовать webpack
, @babel-plugin-syntax-dynamic-import
и loadable-components
.
Webpack
имеет встроенную поддержку динамического импорта, однако, при использовании Babel
для компиляции JSX в JavaScript требуется @babel-plugin-syntax-dynamic-import
. Данный плагин позволяет Babel разбирать (парсить) динамический импорт, чтобы вебпак мог осуществить разделение кода. Ваш файл .babelrc
должен выглядеть примерно так:
1 2 3 4 |
|
loadable-components
- это библиотека для загрузки компонентов с помощью динамического импорта. Она значительно облегчает разделения кода за счет автоматической обработки всех крайних случаев.
1 2 3 4 5 6 7 8 9 |
|
Это все, что нужно сделать. Просто используйте данный компонент в своем приложении. fallback
- это компонент-заместитель на время загрузки настоящего компонента. loadable-components
также может использоваться при рендеринге на стороне сервера.
Восстановление прокрутки¶
Прокрутка на верх страницы¶
В большинстве случаев нам требуется выполнить прокрутку на верх страницы из-за длинного контента, который при навигации, остается "прокрученным". Этого можно добиться с помощью компонента <ScrollToTop>
, который будет выполнять прокрутку при каждой навигации:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Помещаем этот компонент на верхнем уровне приложения, но внутри роутера:
1 2 3 4 5 6 |
|
Если в вашем приложении имеются вкладки, подключенные к роутеру, тогда, возможно, прокрутка на верх страницы при каждом переключении вкладки - это не то, что вам нужно. Как насчет компонента <ScrollToTopInMount>
, выполняющего прокрутку к месту его расположения:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|