Использование Redux с React Router¶
Итак, вы хотите использовать маршрутизацию с Вашим Redux-приложением. Для этого вы можете использовать React Router.
Тогда Redux будет источником правдивых данных, а React Router — единственным источником URL. В большинстве случаев, правильно разделять эти понятия, но до тех пор, пока вам не понадобится путешествовать во времени (Time Travel) и перематывать экшены, которые изменяют URL.
Установка React Router DOM¶
react-router-dom
доступно в npm. В этом руководстве преполагается использование версии react-router-dom@^4.1.1
.
1 |
|
Настройка запасного URL¶
Перед внедрением React Router нам требуется настроить наш сервер разработки. Конечно, наш сервер может не знать о роутах, заявленных в настройках React Router. Например, если вы переходите по ссылке /todos
, то Ваш сервер должен возвращать index.html
, так как это одностраничное приложение. Далее идут примеры настройки популярных серверов.
Важно при использовании Create React App
Если вы используете Create React App, то вам не требуется настраивать запасной URL. Это уже сделано автоматически.
Настройка Express¶
Если вы получаете index.html
из Express:
1 2 3 |
|
Настройка WebpackDevServer¶
Если вы получаете index.html
из WebpackDevServer
, добавьте в webpack.config.dev.js
:
1 2 3 |
|
Подключение React Router к Redux-приложению¶
В этой главе мы будем использовать наш пример Todos. Рекомендуем вам склонировать его для этой главы.
Во-первых, нам надо импортировать <Router />
и <Route />
из React Router. Вот как это делается:
1 2 3 4 |
|
В React-приложении обычно <Route />
оборачивается в <Router />
, так что когда URL меняется, <Router />
находит часть своих роутов и рендерит их сформированные компоненты. <Route />
используется для декларативного сопоставления роутов иерархии компонентов вашего приложения. Вы можете объявить в path
путь, используемый в URL, и в component
— компонент, который должен быть сгенерирован при совпадении с этим URL.
1 2 3 4 5 |
|
Однако, в нашем Redux-приложении нам все еще требуется <Provider />
— компонент высшего порядка, поставляемый с React Redux, который позволяет привязать Redux к React (см. Использование с React).
Далее мы импортируем <Provider />
из React Redux:
1 |
|
Обернем <Router />
в <Provider />
, таким образом обработчики маршрутизации смогут получить доступ к стору
.
1 2 3 4 5 6 7 |
|
Теперь компонент <App />
будет отрендерен, если URL содержит '/'. Кроме того, мы будем добавлять необязательный :filter?
параметр к /
. Нам это потребуется позже, когда мы будем читать параметр :filter
из URL.
1 |
|
Полный код компонента
components/Root.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Нам также надо отрефакторить index.js
, для того, чтобы рендерить <Root />
компонент в DOM.
index.js
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Навигация при помощи React Router¶
React Router поставляется с компонентом <Link />
который позволяет перемещаться по приложению. Если вы захотите добавить некоторые стили, react-router-dom
предоставляет специальный<Link />
называемый <NavLink />
, который принимает параметры стилизации. Параметр activeStyle
позволяет применить стиль активного состояния.
containers/FilterLink.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
components/Footer.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Теперь, если вы кликнете на <FilterLink />
, вы увидите, что URL изменится с '/SHOW_COMPLETED'
, '/SHOW_ACTIVE'
и '/'
. Даже если вы захотите перейти назад, используя соответствующую кнопку браузера, приложение будет использовать для этого историю Вашего браузера и успешно перейдет к предыдущему URL.
Чтение из URL¶
Сейчас todo list не фильтруется после изменения URL. Это происходит потому, что фильтрация описана в функции mapStateToProps()
компонента <VisibleTodoList />
, которая в свою очередь связана с состоянием
, а не с URL. mapStateToProps
имеет второй необязательный аргумент ownProps
— объект, содержащий все параметры, переданные в <VisibleTodoList />
.
containers/VisibleTodoList.js
1 2 3 4 5 6 7 8 9 |
|
В данный момент мы ничего не передаем в <App />
, поэтому ownProps
является пустым объектом. Чтобы отфильтровать наши todos в соответствии с URL, нам надо передать параметры URL в <VisibleTodoList />
.
Когда мы написали: <Route path="/:filter?" component={App} />
, это позволило в компоненте App
получить доступ к параметру params
.
Параметр params
— это объект со всеми параметрами из URL, доступный в объекте match
. Например, match.params
эквивалетно { filter: SHOW_COMPLETED' }
, если URL localhost:3000/SHOW_COMPLETED
. Теперь мы можем считывать URL из компонента <App />
.*
Важно помнить, что мы используем ES6-деструкцию на параметрах, чтобы передать их в params
в <VisibleTodoList />
.
components/App.js
1 2 3 4 5 6 7 8 9 10 11 |
|
Следующие шаги¶
Теперь, когда мы знаем основы создания простой навигации, мы можем перейти к изучению React Router API.
Помните, что существуют и другие библиотеки для навигации по приложению
Redux Router — экспериментальная библиотека, она позволяет Вам хранить все состояние Вашего URL в redux сторе. У нее то же самое API, что и у React Router, но сообщество и поддержка меньше, чем у React Router.
React Router Redux создает связь между Вашим Redux-приложением и React Router и позволяет их синхронизировать. Без этой связи у Вас не будет возможности перемещаться по экшенам при помощи Time Travel. Пока Вам это не требуется, React-router и Redux могут работать совершенно независимо.