React Router
React прекрасно подходит для построения пользовательских интерфейсов. Если я вас еще не убедил, вернитесь и перечитайте предыдущие главы! React также может использоваться для реализации простой маршрутизации URL с нуля, как было показано для router.jsx.
Но для более сложных одностраничных приложений (SPA) требуется более широкая функциональность. Например, передача параметра в URL — стандартный способ передачи отдельных элементов вместо списка: например, /posts/57b0ed12fa81dea5362e5e98, где 57b0ed12fa81dea5362e5e98 — уникальный идентификатор сообщения. Для извлечения параметра из URL можно воспользоваться регулярным выражением; но рано или поздно, когда сложность вашего приложения возрастет, вам, возможно, придется заново изобретать уже существующие реализации маршрутизации URL.
Семантические URL-адреса
Семантические URL-адреса (https://ru.wikipedia.org/wiki/Семантический_URL) улучшают удобство использования и доступность веб-сайта или веб-приложения за счет отделения внутренней реализации от пользовательского интерфейса. В несемантическом решении могут использоваться строки запросов и/или имена файлов сценариев. С другой стороны, при семантическом подходе пути используются только таким способом, который помогает пользователям интерпретировать структуру и работать с URL. Приведу несколько примеров.
Несемантические URL (неплохо)
Семантические URL (лучше)
http://webapplog.com/show?post=es6
http://webapplog.com/es6
https://www.manning.com/books/react-quickly?a_aid=a&a_bid=5064a2d3
https://www.manning.com/books/react-quickly/a/5064a2d3
http://en.wikipedia.org/w/index.php?title=Semantic_URL
https://en.wikipedia.org/wiki/Semantic_URL
Многие фреймворки, такие как Ember, Backbone и Angular, содержат встроенные механизмы маршрутизации. Что касается маршрутизации в React, существует React Router (react-router; https://github.com/reactjs/react-router) — готовое, полноценное решение. В разделе 13.4 будет рассмотрена реализация для Backbone; там показано, как хорошо React сочетается с этим фреймворком в стиле MVC, который используется многими разработчиками для построения SPA-приложений. А пока сосредоточимся на React Router.
React Router не входит в официальную базовую библиотеку React. Эта библиотека была разработана сообществом, но она достаточно популярна и проверена временем, чтобы использоваться в трети проектов React42. Большинство React-разработчиков, с которыми я общался, выбирает ее по умолчанию.
Синтаксис React Router использует JSX, и это дополнительный плюс, поскольку разработчик может создавать более удобочитаемые иерархические определения, чем с объектом mapping (как в предыдущем проекте). Как и наша наивная реализация, библиотека React Router содержит компонент React Router (и он в каком-то смысле вдохновил мою реализацию!). Основные шаги, которые необходимо выполнить для его использования:
1. Создайте мэппинг, преобразующий URL в компоненты React (которые преобразуются в разметку на веб-странице). В React Router эта задача решается передачей свойств path и component, а также внешнего объекта Route. Мэппинг определяется в JSX объявлением и вложением компонентов Route. Эта часть должна быть реализована для каждого нового проекта.
2. Используйте компоненты React Router Router и Route, которые творят волшебство с изменением представлений в соответствии с изменениями в URL. Разумеется, эту часть реализовать вам не придется, но библиотеку нужно установить.
3. Выполните рендер компонента Router на веб-странице, подключая его к ReactDOM.render() как обычный элемент React. Не стоит и говорить, что эта часть должна быть реализована для каждого нового проекта.
JSX используется для создания объекта Route для каждой страницы, а также для вложения его в другой объект Route или Router. Объект Router находится в функции ReactDOM.render(), как и любой другой элемент React:
ReactDOM.render((
...
), document.getElementById('content'))
Каждый объект Route содержит как минимум два свойства: path (шаблон URL, совпадение которого активизирует маршрут) и component (выборка и рендеринг необходимого компонента). Для Route также можно определить другие свойства, например обработчики событий и данные. Они будут доступны в свойстве props.route этого компонента Route. Так происходит передача данных компонентам маршрутов.
Для демонстрации рассмотрим пример SPA-приложения с маршрутизацией по нескольким страницам: About, Posts (некое подобие блога), Post, Contact Us и Login. Эти страницы имеют разные пути и рендерятся разными компонентами:
• About — /about
• Posts –/posts
• Post — /post
• Contact — /contact
Страницы About, Posts, Post и Contact Us имеют одинаковый макет (компонент Content) и осуществляют рендер внутри него. Начальная (не финальная!) версия кода с использованием React Router выглядит так:
Интересно, что маршруты могут вкладываться для повторного использования макетов из родителей, а их URL-адреса могут быть независимыми от вложения. Например, возможно иметь вложенный компонент About с URL-адресом /about, хотя маршрут «родительского» макета Content использует /app. Компонент About также будет содержать макет Content (реализованный посредством this.props.children в Content):
...
Другими словами, About не требуется вложенный URL-адрес /app/about, если только вы не захотите, чтобы это было именно так. Тем самым достигается большая гибкость в отношении путей и макетов.
Для навигации будет реализовано меню, изображенное на рис. 13.2. Меню и заголовок будут отрендерены из Content и повторно использованы на страницах About, Posts, Post и Contact Us. На иллюстрации стоит обратить внимание на ряд моментов: рендерится страница About, кнопка в меню активна, URL отражает тот факт, что текущей является страница About (секция /#/about), а текст Node.University отражает текущее содержимое компонента About (об этом позднее).