Привет Реагировать

В предыдущем посте мы подробно описали причины, по которым мы отказались от Backbone. В этом выпуске мы расскажем, как мы организовали поиск, который привел нас к React, а затем углубимся в Учебное пособие по React о том, как мы пишем компоненты React в Gusto.

Оптимизация для вашего собственного варианта использования

При оценке вариантов обновления вы должны тщательно продумать, каковы наиболее важные варианты использования вашего приложения и как вы можете выбрать технологию, которая оптимизируется для них. Для нас мы оптимизировали 3 вещи:

Путь инкрементного обновления

Мы создали большое монолитное внешнее приложение, и нам нужно было быть прагматичными в том, как мы подошли к пути обновления. Полностью переписать наше внешнее приложение было невозможно. Нам нужен был фреймворк без высоких начальных затрат, который позволил бы нам постепенно мигрировать наше приложение. Это позволило бы нам продолжать создавать постоянный поток функций для наших клиентов во время перехода с Backbone на React.

Повторное использование общих компонентов

Пройдя ребрендинг и обновление макета только за последний год, мы понимаем ценность консолидации разметки и повторного использования общих компонентов в приложении. Имея единый источник достоверной информации для всех строительных блоков пользовательского интерфейса в приложении, обновления дизайна становятся намного проще в развертывании, и мы можем быть уверены в их влиянии на все приложение.

Простота создания интерактивных форм

Как компания, занимающаяся расчетом заработной платы, льготами и персоналом, у нас больше возможностей для ввода данных и интерактивных форм, чем у большинства других веб-приложений. Будь то прием на работу сотрудника, начисление заработной платы или выбор новых планов медицинского страхования, мы чаще собираем информацию от наших пользователей, а не предоставляем представления для использования данных. В результате мы выбрали фреймворк, который оптимизируется для уровня представления и позволяет декларативно писать реактивные формы.

Введите React.js

Выбор надежных и проверенных технологий имеет решающее значение при расчете заработной платы и льгот, и React впервые привлек наше внимание своим интенсивным использованием в Facebook и Instagram.

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

Декларативный пользовательский интерфейс

В React есть система привязки данных, состоящая из внутренних state и props. state можно обновить в ответ на пользовательские события с помощью вызова setState, а props — это аргументы, передаваемые компоненту для упрощения повторного использования. Поскольку изменения state и prop вызывают немедленную повторную визуализацию компонента, мы получаем встроенную привязку данных, которая позволяет нам писать компоненты, которые носят декларативный характер и будут автоматически обновляться на основе изменений этих свойств. Это означает отсутствие ручных обновлений DOM и сложной логики if/else для определения того, что нужно изменить, а скорее четкое определение того, как наш компонент будет выглядеть на основе заданного состояния.

Оптимизированные обновления DOM

Shadow DOM в React стал огромным событием для сообщества JS, о чем свидетельствует его широкое распространение такими фреймворками, как Ember и Angular. React имеет внутреннее представление того, что находится в DOM, и всякий раз, когда в модель данных вносятся изменения, новый DOM будет пересчитываться в памяти (быстро) и выполнять минимально возможные операции для обновления DOM до нового состояния.

Инкапсулированный/составной

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

Тестируемый

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

Хорошо взаимодействует с нашей командой дизайнеров

У нас в Gusto есть команда дизайнеров-звезд, и мне было приятно работать с ними над нашим растущим пользовательским интерфейсом. Они владеют нашими элементами и облегчают нашу работу как инженеров, предоставляя все основные строительные блоки, необходимые для создания функций без необходимости написания пользовательской разметки. Имея возможность использовать повторно используемые компоненты, которые являются гибкими и стильными, мы можем быстро создавать интерфейсы, которые соответствуют бренду, функциональны и красивы.

Немедленный рост производительности

Поскольку React — это только уровень представления вашего приложения, он оставляет маршрутизацию и управление данными на ваше усмотрение. Мы уже создали надежную модель данных на основе Backbone, которая была хорошо интегрирована с нашими RESTful JSON API, и мы надеялись повторно использовать ее в новой системе. Мы смогли добиться этого, абстрагировав наши модели Backbone за хранилищами Flux и сделав наши компоненты независимыми от нижележащего уровня данных, предоставив нам легко заменяемый слой для взаимодействия с Backbone.

Интеграция React в наше приложение

React не только позволяет легко использовать нашу модель данных Backbone, но и может отображать ее с помощью представлений Backbone и маршрутизаторов. Это имело решающее значение для того, чтобы мы могли сразу начать писать React и преобразовывать представления Backbone по мере необходимости, а не все сразу. Мы по-прежнему используем маршрутизаторы Backbone для обработки URL-адресов на стороне клиента, и мы просто расширили их для обработки компонентов React.

class BenefitsRouter extends Backbone.Router  
  initialize: (options) ->
    @company = options.company
  routes:
    'benefits': 'benefits'
  ...
  benefits: (highlight) ->
    view = React.createElement(BenefitsPage)
    AppView.showView(view, 'company-benefits')

Наш AppView — это наш контейнер приложения, который обрабатывает отображение того представления, которое находится в фокусе. Мы используем функцию showView для анимации между разными страницами, и мы модифицировали ее, чтобы соответствующим образом монтировать представления Backbone и React.

Хотя мы пытаемся писать полные представления в React, иногда необходимо отображать React из представлений Backbone.

class AddressView extends Backbone.View  
  template: HandlebarsTemplates['addresses/address']
  className: 'address-address-view'
  mixins: [ReactSubComponent]
  render: ->
    @unmountSubComponents()
    @$el.html(@template(@context()))
    @renderAddressExtensionView()
    return @
  ...
renderAddressExtensionView: ->
    view = React.createElement(AddressExtension, { addressId: @model.id })
    @renderSubComponent(view, @$('.address-extension-view').get(0))

Нам предоставляется метод renderSubComponent из небольшого миксина, который мы написали, который подключается к Coccyx, чтобы компоненты React правильно удалялись вместе с представлением. Обратите внимание, что здесь мы не передаем модель Backbone в компонент, а просто передаем идентификатор, чтобы компонент мог сам получить данные из хранилища. Это гарантирует, что если нам понадобится удалить Backbone в будущем, наши компоненты React будут использовать интерфейс хранилища, который мы можем реорганизовать.

Рука помощи

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

Неизменяемый.js

Immutable.js — еще одна замечательная библиотека, выпущенная Facebook, которая позволяет нам быть уверенными в том, что объекты, с которыми мы работаем, не изменятся неожиданно. Например, если бы вы обновили объект state в компоненте React без использования метода setState, жизненный цикл React был бы нарушен, поскольку он не смог бы зафиксировать изменения. Иногда при совместном использовании изменяемых объектов изменения могут происходить в удаленных областях приложения, которые трудно отследить. Столкнувшись с этой проблемой слишком много раз, мы решили принять Immutable для всех наших сложных объектов, используемых в наших компонентах.

Immutable — это функциональная библиотека, которая предоставляет мощные методы для обновления вложенных объектов и всегда возвращает новую копию обновленного объекта. Гарантированная неизменность позволяет проще рассуждать о наших данных, используемых нашими компонентами. Это также позволяет уверенно использовать PureRenderMixin, потому что, хотя эта оптимизация рассматривает только неглубокое равенство, чтобы определить, нужно ли обновлять часть дерева, наличие другого неизменяемого объекта гарантирует, что изменение произошло.

Фермент

Enzyme — это тестовая библиотека, разработанная AirBnB, чтобы сделать тестирование компонентов React интуитивно понятным. Исходя из фона Backbone, где jQuery часто является библиотекой, используемой для подтверждения правильности построения DOM, тестовые утилиты React кажутся неуклюжими и запутанными по сравнению с ними. Enzyme предоставляет знакомый нам API (гибкий метод find, который может одинаково утверждать классы, теги и компоненты React), а также дает нам простые варианты поверхностного, полного и статического рендеринга.

Flux, Babel, ESLint, Webpack

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

Мы в восторге от нашей новой настройки и надеемся, что эта статья продемонстрирует некоторые сильные стороны React и проблемы, которые он решает для нас.

Теперь, когда мы рассмотрели причины перехода с Backbone на React, мы хотели бы продемонстрировать фактическое создание приложения React. Следующий пост в этой серии под названием Развитие JavaScript, часть 3: создание приложения React посвящен именно этому.

Комментарии к Хакер Новости

Первоначально опубликовано на сайте engineering.gusto.com 12 июля 2016 г.