|
|
|||||||||||||||||||||||||||||
|
React: создание простых в обслуживании, быстродействующих компонентов пользовательского интерфейсаИсточник: ibm
JavaScript - который поддерживается всеми современными браузерами и бесспорно является де-факто естественным языком веб-программирования - имеет прямой доступ ко всему богатству функций "веб как платформы". Сложные JavaScript-проекты все чаще выходят за рамки возможностей программистов-одиночек и переходят в руки крупных команд разработчиков. Этот сдвиг несет с собой целый букет проблем. Работающий код, основанный на хитроумных решениях, становится недоступным для понимания и обслуживания другими. Новичку может понадобится много времени, чтобы освоить сложную систему. Постоянно растущая база кода не допускает многократного использования в рамках команды в целом. А неуловимые, неустойчивые аномалии производительности часто проявляются только в промышленных, эксплуатируемых системах. Эти проблемы хорошо знакомы разработчикам передовых социальных сетей, создающих конкурентоспособные и сложные веб-интерфейсы, которыми ежедневно пользуются миллионы. В 2013 году компания Facebook/Instagram выпустила проект React - библиотеку компонентов пользовательского интерфейса - как проект ПО с открытым исходным кодом, предоставив программистам возможность познакомиться с тем, как она справляется с этими болезнями роста. Разработчики JavaScript, которым, приходится сталкиваться с теми же трудностями, с энтузиазмом встретили React и сопутствующие практические рекомендации. Это руководство знакомит читателя с библиотекой React и объясняет, как она работает, а также дает практические рекомендации и учит быстро программировать на конкретных примерах. Освоив его, вы сможете создавать собственные многоразовые React-компоненты или компоновать их из сотен готовых компонентов с открытым исходным кодом, разработанных сообществом. Библиотека React для создания многоразовых компонентов пользовательского интерфейса
React предоставляется в виде библиотеки JavaScript с компилятором JSX и связанных с ними инструментов разработки. React облегчает создание многоразовых быстродействующих компонентов представления, которые можно использовать для создания современных веб-интерфейсов. Следуя практическим рекомендациям, вы сможете создавать такие простые в обслуживании многоразовые компоненты. Для оптимизации быстродействия компоненты React сначала преобразуются в управляемую модель Virtual DOM , как показано на рисунке 1. Рисунок 1. Работа ReactРабота в абстрактном режимеМодель Virtual DOM работает в React в абстрактном режиме . Вы декларативно описываете, как ваш пользовательский интерфейс должен выглядеть и вести себя (в форме графа сцены JSX компонентов, подлежащих визуализации), а затем механизм исполнения подыскивает оптимизированный способ его воспроизведения. Работа в абстрактном режиме (retained-mode) позволяет выполнять оптимизацию для достижения высокой производительности рендеринга и широко применяется в работе с 3D-графикой, включая популярные игровые механизмы и WebGL-платформы; он также реализован в современных платформах приложений, таких как Famo.us. Вы декларативно описываете иерархию компонентов своего пользовательского веб-интерфейса и вводите ее в виртуальную модель DOM React. Затем React заботится о синхронизации вашего пользовательского интерфейса с фактической DOM-моделью браузера в соответствующие моменты времени. Реализация модели Virtual DOM React самодостаточна и не зависит от браузера; ее даже можно использовать для рендеринга на стороне сервера. Virtual DOM выполняет оптимизированное сравнение своего внутреннего состояния с DOM-моделями браузеров и вносит минимальные изменения, необходимые для сохранения согласованности пользовательского интерфейса. Этот подход абстрактного режима решает большой класс проблем производительности, связанных с непосредственным изменением элементов DOM браузера при каждом визуальном переходе (именно так работают популярные библиотеки компонентов пользовательского интерфейса, такие как jQuery UI). В отличие от аналогичных библиотек, React не применяет стандартный стиль управления состоянием и разработки пользовательского интерфейса "модель-представление-контроллер" (MVC). Вместо этого, React занимается исключительно созданием представлений, и участники проекта объясняют, почему MVC - не лучший способ создания сложных веб-интерфейсов. Однако в React нет ничего, что мешало бы использовать конструкцию MVC; многие разработчики в начале работы с React вставляют новый код в уровень представления существующих крупных проектов на основе MVC. Ловушки MVC при создании сложных современных пользовательских интерфейсовТрадиционные многостраничные веб-приложения тоже могут содержать по несколько экземпляров MVC на страницу, однако при разработке современных одностраничных приложений с высоко интерактивными компонентами пользовательского интерфейса создание и обслуживание многих экземпляров взаимосвязанных MVC просто необходимо. Эти MVC связаны друг с другом сложными взаимосвязями: несколько контроллеров могут совместно использовать общую модель, или один контроллер во время работы может зависеть от других. Экземпляры модели часто организованы как структуры данных в памяти, представляющие изменяемое состояние приложения, которые прямо или косвенно используются контроллерами. Эта ситуация может приводить к путанице моделей данных (и их вычисляемых или производных версий), проходящих сквозь сеть MVC, что затрудняет определение единого источника истины для управляемых фрагментов данных в любой момент времени. В качестве примера группа React приводит трудности с прослеживанием "каскадных обновлений", распространяемых по запутанной сети MVC. Зачем понадобилась еще одна библиотека JavaScript для пользовательского интерфейсаВот некоторые преимущества библиотеки React:
Объединение декларативного описания пользовательского интерфейса с логикой JSXJSX - это преобразователь и компилятор, воспринимающий расширенный синтаксис JavaScript. JSX переводит расширенную HTML-подобную запись вроде следующей: <div> <MyLabel text={TextLabel} /> <MyTextfield /> <MyButton textlabel='OK' /> </div>
...в вызовы JavaScript API React: React.createElement("div", null, React.createElement(MyLabel, {text: TextLabel}), React.createElement(MyTextfield, null), React.createElement(MyButton, {textlabel: "OK"}))
Экспериментирование с JSX в онлайнеЧтобы гораздо лучше изучить JSX, можно "поиграть" с интерактивным онлайн-компилятором JSX. Знакомая HTML-подобная форма записи JSX значительно упрощает кодирование и обслуживание компонентов React. Это упрощение особенно очевидно при объявлении соотношений между глубоко вложенными компонентами. JSX позволяет разместить логику пользовательского интерфейса вместе с соответствующим структурным описанием в одном файле, что помогает повысить производительность труда и уменьшить количество ошибок в крупных проектах. При использовании других платформ может потребоваться синхронизировать в три раза больше файлов: файлы шаблона, обработчика кода JavaScript и структурного описания HTML. Развертывание JSXJSX может выполняться в браузере или самостоятельно. Преобразователь, встроенный в браузер, помогает при разработке, потому что после изменения JSX-кода результаты видны сразу. При выпуске промышленных продуктов для лучшей производительности в цепочку сборки необходимо включить отдельный преобразователь. Во всех примерах этого руководства для простоты используется преобразователь, встроенный в браузер. Первый пример (example1) извлекает React и JSX-преобразователь из сети доставки контента (CDN) и демонстрирует простейший способ получить работающее приложение (файлы размещаются за веб-сервером и обращаются к своим URL-адресам): <html lang="en"> <head> <script src="http://fb.me/react-0.12.2.js"></script> <script src="http://fb.me/JSXTransformer-0.12.2.js"></script> <script type="text/jsx" src="example1.jsx"></script> </head> <body>
В примерах example2 и example3 для установки React используется менеджер пакетов bower; они обращаются к локально установленным копиям JSX-преобразователя в браузере. Так, пример example2.html извлекает два файла: <script src="bower_components/react/react-with-addons.js"></script> <script src="bower_components/react/JSXTransformer.js"></script>
В обоих случаях можно поэкспериментировать с React, изменяя JSX-файлы и перезагружая браузер, чтобы увидеть результат. Создание специальных компонентов ReactТеперь мы быстро создадим с помощью React компонент, используя код из example1.jsx: var MyTextfield = React.createClass({ render: function() { return <input type='text' />; } });
Вот и все. Этот простой специальный компонент React, показанный на рисунке 2 вместе с другими компонентами React, обрабатывает неконтролируемое поле ввода , упаковывая базовый HTML-элемент Рисунок 2. Компоненты React
|
Компонент React | Описание | Важные состояния/свойства |
---|---|---|
<MyTableCell> |
Ячейка обновляемой таблицы. Содержит контролируемый элемент <input> и элемент <button> . Элемент <input> отключен, а <button> имеет значение {display: none} , пока значение ячейки не редактируется. |
editing : следит за тем, редактируется ли ячейка.
|
<MyTable> |
Многострочная таблица, содержащая в каждой строке экземпляр <MyTableCell> . |
Без сохранения состояния. data - свойство, массив значений hash , содержащий элементы text и value для заполнения каждой строки. onUpdate - свойство обратного вызова, включается после сеанса редактирования, передавая информацию измененной ячейки. |
<MyBarChart> |
Контроллер-представление. Отображает экземпляр <BarChart> с помощью стороннего компонента React. Взаимодействует с хранилищем Flux, получая уведомление при изменении статистики сайта. |
stats : массив значений hash , содержащий элементы text и value ; источник данных для диаграммы. |
<MyTableWrapper> |
Контроллер-представление. Взаимодействует с диспетчером Flux, отправляя действие обновления sitestats при изменении значения ячейки таблицы. |
sitestats : массив значений hash , содержащий элементы text и value ; отслеживает текущие значения таблицы. |
<EditableChart> |
Составляет <MyBarChart> и <MyTable> , формируя окончательный UI. |
Без сохранения состояния. data - это свойство, источник исходных данных, извлекаемых из хранилища Flux, которые отображаются в составных компонентах. |
Большая часть кода работает только с виртуальной моделью DOM. Однако в некоторых ситуациях требуется доступ к фактической модели DOM браузера. Один из примеров - когда нужна интеграция с существующей библиотекой, такой как jQuery Mobile и D3; другой пример находится в обработчике _cellClicked()
в компоненте <MyTableCell>
. После того как на ячейке щелкнули, она переходит в режим редактирования, и фокус перемещается к фактическом элементу модели DOM браузера <input>
. Это делается с помощью задержанного вызова getDOMNode()
:
refs
используется для доступа к элементам, созданным во время рендеринга в виртуальной модели DOM (по аналогии с getElementById()
в модели DOM браузера).
В компоненте <MyTableWrapper>
все свойства передаются на обернутый экземпляр <MyTable>
. Однако значение свойства onUpdate
должно быть переопределено и направлено к своему обратному вызову _dataUpdated
. Для этого используется форма распространенных атрибутов JSX:
В компоненте <EditableChart>
начальное значение по умолчанию свойства sitestats
извлекается из хранилища Flux. Для передачи этого начального значения по умолчанию используется getDefaultProps
. React кэширует значение для последующего использования:
Для стилевого оформления приложения используются обычные CSS. Например, в примере example3.css для стилевого оформления приложения предусмотрен код flexbox CSS3:
Обратите внимание на использование свойства className
в <EditableCell>
для задания класса CSS (во избежание конфликта с ключевыми словами JSX):
Если есть стили, которые могут меняться в зависимости от внутреннего состояния компонента, то можно выполнить стилизацию и в JavaScript с помощью встроенного стилевого оформления. <MyTableCell>
содержит нативный <button>
, который стилизуется посредством встроенного JavaScript:
Flux - это один из подходов к построению приложений с использованием компонентов React. Он определяет архитектуру с односторонним потоком данных, которая решает проблемы, связанные с взаимодействующими сетями MVC, имеющими место в сложных пользовательских интерфейсах, и улучшает эксплуатационную технологичность базы кода в долгосрочном плане.
Вкратце, общее изменяемое состояние приложения, используемое при рендеринге компонента, передается на более высокие уровни. Традиционные контроллеры заменены на контроллеры-представления (представления объекта верхнего уровня - такие как <MyBarChart>
и <MyTableWrapper>
в примере example3, - которые управляют состоянием, отображаемым собственными субпредставлениями). Теперь операции традиционной модели выполняются посредством передачи действий в соответствующие хранилища через дноэлементный диспетчер. Действия - это пакеты данных, которые декларируют выполняемую операцию и связанные с ней данные. (Тесно связанные вызовы методов превращаются действиями в поток слабо связанных данных). Хранилища и их взаимозависимости обрабатываются через диспетчер слабо связанным образом. (Проектировщики структур могут заметить сходство со структурами Command and Chain of Responsibility, а системным инженерам это напомнит маршалинг и сериализацию ).
Контроллеры-представления никогда не передают состояние приложения друг другу - прямо или косвенно. Они регистрируют свою заинтересованность в изменениях данных в хранилищах, а хранилища в случае изменений уведомляют представления о том, что им нужно забрать данные (и обновляют свое собственное управляемое состояние). Это единственный поток данных, входящий в эти представления. Этот односторонний поток данных показан на рисунке 6.
Код примера example3 по своей конструкции приблизительно повторяет схему Flux - с реализацией макета единственного хранилища. Компонент <MyBarChart>
регистрирует все изменения данных в MockSiteStatsStore
. Уведомление от хранилища - единственный способ изменения управляемого состояния <MyBarChart>
.
Любое интерактивное изменение данных, выполненное в <MyTableWrapper>
, пропускается как действие через диспетчер/хранилище посредством вызова MockSiteStatsAction.update()
. Несмотря на то, что два компонента соседствуют в том же пользовательском интерфейсе, они не обмениваются состояниями напрямую. Односторонний поток данных проходит от <MyTableWrapper>
через диспетчер в заинтересованный компонент MockSiteStatsStore
, а затем через уведомления об изменении возвращается в <MyBarChart>
.
Подробный анализ структуры приложения Flux выходит за рамки настоящей статьи.
В веб-магазине Chrome есть полезное расширение для браузера Chrome React Developer Tools. Оно позволяет в процессе отладки просматривать иерархию компонентов React приложения - вместо менее наглядного DOM-представления браузера. На рисунке 7 показано, как выглядит иерархия компонентов example3 при установленном React Developer Tools.
В качестве дополнения для работы кодом React также предлагается профилировщик.
На конференции React.js в январе 2015 года были анонсированы расширения Relay для Flux и React Native. На момент написания этой статьи ни одно из них не выпущено в виде ПО с открытым исходным кодом.
Relay дополняет Flux возможностью извлечения данных с сервера. Ключевая идея Relay - возможность для каждого компонента React самостоятельно указывать свои собственные требования по извлечению данных. Как правило, это относится к данным, используемым для визуализации самого компонента. Relay позволят статически объявлять требования компонента к данным в том же файле (JSX), где находится логика пользовательского интерфейса. Это значительно сокращает характерный беспорядок в файлах при работе со сложными, полноценными приложениями. Это также позволяет немедленно проверять корректность и синхронизацию в процессе разработки, перезагружая браузер после редактирования файла JSX.
В Relay применяется важная технология GraphQL - свободно компонуемый декларативный язык описания запросов произвольно оформленных данных. (Facebook уже пару лет использует GraphQL в промышленном режиме.) GraphQL позволяет высокоуровневым компонентам составлять требования своих собственных компонентов - независимо от содержания самих требований - и собирать комбинированный запрос к серверу.
Результаты GraphQL-запросов хранятся в хранилище Flux general common
, где подписавшиеся представления уведомляются об обновлении данных.
React Native заменит DOM браузера для платформы Android или iOS. Это позволит разработчикам React оптимизировать свои приложения для мобильных устройств.
В React Native код JavaScript выполняется в своем системном потоке с применением собственного интерпретатора. С нативной платформой код React соединяет так называемый высокопроизводительный асинхронной пакетный мост - согласовывая нативные компоненты UI с конкретной реализацией пользовательского интерфейса. Можно также создавать специальные нативные методы для доступа JavaScript через этот мост. HTML-элементы в React заменяются нативными представлениями и UI-виджетами на мобильной платформе. React Native будет поддерживать стилизацию нативных компонентов через подмножество CSS поверх JavaScript.
По словам разработчиков, приложения, созданные с помощью React Native, смогут точно воспроизводить тонкие нюансы интерфейса, которые у пользователей ассоциируются только с нативными приложениями - существующие сегодня альтернативы на основе WebViews или HTML5 не могут этого обеспечить.
При создании пользовательских интерфейсов для своих проектов JavaScript-разработчики могут выбирать платформы и библиотеки с открытым исходным кодом из огромного разнообразия. Но лишь немногие из них прошли испытания в сложных проектах, где требуется высокая производительность; еще меньше снабжены мощными инструментами поддержки и сопровождаются проверенными практическими рекомендациями по программированию и проектированию при гарантированной перспективе будущего роста, которая распространяется на операции с данными на сервере и разработку для мобильных устройств. React предлагает все это и многое другое - при ширящейся активной поддержке сообщества. Сегодня самый подходящий момент для того, чтобы добавить React к своему набору инструментов разработки.
Главная страница - Программные продукты - Статьи - Управление ИТ-инфраструктурой, Big Data, IBM, IBM Big Data |
Распечатать »
Правила публикации » |
Написать редактору | |||
Рекомендовать » | Дата публикации: 24.09.2015 | |||
|
Новости по теме |
В России изготовлены фотонные интегральные схемы 90 нм и 350 нм
|
Рассылки Subscribe.ru |
Статьи по теме |
Новинки каталога Download |
Исходники |
Документация |