React vs Angular. Записки UI разработчика.
Привет. В этой статье мы проанализируем плюсы и минусы в фреймворке Angular и библиотеке React, а также сравним этих титанов из мира frontend между собой. Эти технологии подарили разработчикам следующие возможности: переиспользование, рефакторинг, разделение на модули, чем облегчили им жизнь и это лишь часть плюсов от использования Angular или React.Но нужно понимать, что такое сравнение этих технологий не может быть полным, т.к. Angular это MVC / MVVM-фреймворк (условно MVC), а React – библиотека с большим количеством пакетов и открытым исходным кодом для интеграции. Чтобы создать общее приложение на React нужны еще дополнительные библиотеки для:
- маршрутизация (реакция-роутер)
- управление состоянием (baobab, Redux, MobX, RxJS), (можно обойтись и без него, но это не рекомендуется). В Angular он тоже не встроенный, вы можете использовать отличный RxJS, @ngrx или просто сервисы)
- проверка формы (реакция-проверка, форма-реакция, редукс-форма)
- анимации
- HTTP абстракция (или просто использовать fetch)
Angular 2+ предоставляет большинство из них прямо из коробки, имеет официальные примеры и руководства по стилю, как все это использовать. Концепция Angular более монолитна и связана с SPA, сам React небольшой и быстрый, и его можно использовать не только для SPA, но и для «анимации» только частей классического серверного приложения (PHP / Ruby / Python или других) , как старый AngularJS. Таким образом, они даже могут быть использованы вместе.
@Selector в Angular это имя класса компонента в React. Разница лишь в том, что селектор Angular отображается в DOM, а класс в React лишь визуализирует материал с помощью метода render, не создавая при этом дополнительные узлы.
@Input в Angular можно прировнять к props в React. Это объект, содержащий все входные данные для компонента. Props не должен изменяться. Для этого у компонент есть state – изолированый контейнер состояния. В сравнении – у Angular компонентов может быть сколько угодно много @Input в которых можно передавать параметры по отдельности, а не целым объектом, в случае как с Props.
@Output – способ дочернего компонента дать обратную связь родительскому компоненту при помощи EventEmitter (генерации событий, с обработчиком на стороне родителя). Таким образом можно «наверх» любые данные. В React аналогов нет, поэтому для того, чтобы выполнить какой-либо колбэк для получения информации из дочернего компонента, этот колбэк прокидывают в дочерний компонент и вызывают там.
@ViewChild – способ в Angular получить доступ к DOM элементу. Аналоги в React – ref, сокращенно от reference (ссылка). Но по возможности, лучше избегать ref в пользу props.
Ключевые отличия
Проведём быстрое сравнение:
Angular | Описание | React |
Разработчик | ||
2016 | Релиз | 2013 |
Фреймворк | Тип | Frontend-библиотека |
Высокий | Порог вхождения | Средний |
HTML + TypeScript | Шаблон | JSX + JS (ES5/ES6) |
Двусторонняя | Привязка данных | Односторонняя |
Обычный DOM | DOM | Виртуальный DOM |
Сильная | Абстракция | Средняя |
Фреймворк VS Библиотека
Angular является фреймворком, а React — это библиотека.
React сам по себе предназначен для создания представлений (это «V» в MVC). Что может сделать React, так это создать представления с помощью компонент. В таком виде данные могут передаваться по цепочке от родительских компонент к дочерним. Чтобы заполнить эту пустоту, Facebook разработал Flux, который является архитектурным шаблоном, который дополняет React. Flux архитектура в сочетании с React обеспечивает следующий сценарий:
- Пользователь нажимает на элемент React.
- Действие активируется. Это действие отправляется в Store через библиотеку Dispatcher.
- Хранилище отслеживает состояние приложения и методы извлечения данных. Любое обновление состояния отражается в представлениях, и это помогает сохранить соответствие представлений с состоянием приложения.
Flux дополняет React и реализует концепцию однонаправленного потока данных.
Angular является фреймворком для создания клиентских приложений
Angular – это название, которое подразумевает под собой фреймворк, начиная с версии 2. Все версии до второй было принято называть AngularJS, т.к. различия между первой и второй версиями были фундаментальными.
AngularJS был прочно построен поверх шаблона MVC, который отделял приложение от трех разных слоев. Комбинация модели, представления и контроллера плюс дополнительная сложность, связанная с овладением директивами, фабриками, службами и другими компонентами для создания одностраничного приложения, заставила разработчиков Google перейти к компонентной архитектуре.
Но с ростом приложения, важно иметь прочную структуру, которая отделит мух от котлет – хранение бизнес-логики подальше от представлений. Angular позволяет вам осуществлять структурную организацию, перемещая бизнес-правила в модель домена (используя комбинацию классов моделей и сервисов) и вставляя модель в свои компоненты посредством инъекции зависимостей.
Ниже приведен пример кода, который иллюстрирует, как бизнес-логика инкапсулируется внутри модели пользователя и службы пользователя, и убирается подальше от нашего компонента.
Компонентный подход
Компоненты — это самый базовый строительный блок пользовательского интерфейса в приложении. Приложение представляет собой дерево компонентов.
Что такое компоненты? В Angular компоненты — это классы, написанные при помощи TypeScript, над которыми помещен декоратор @Component. Внутри самих декораторов мы можем перечислить метаданные, такие как шаблон представления, стили, селектор и т.д.
Иерархия компонентов в Angular спроектирована таким образом, что вы можете связывать структуру и функциональность под одним объектом. Ниже представлен высокоуровневый архитектурный обзор компонентов и как это связано со всем остальным в Angular.
Архитектура Angular. Компонент в центре, и все остальное вращается вокруг него.
Совместное использование данных между компонентами возможно с помощью вложенных компонентов, как показано ниже.
Концепция компонентов является основой как в React, так и в Angular. Однако, в отличие от Angular, React-компоненты — это просто функции JavaScript с произвольным количеством входных данных и одним выходом. В приведенном ниже коде показан компонент, определенный с помощью функции JavaScript и использующий класс ES6.
Впредь для составления компонентов, по рекомендациям Facebook, для составления компонент, будем придерживаться стандартов ES6.
Каждый компонент React может принимать бесконечное количество входных параметров, которые сохраняются в объекте props.
У любого компонента должен быть метод render, определяющий, что отобразить при вызове компонента. Метод render вызывается каждый раз, когда происходит изменение состояния компонента (this.state).
Особенности языка: TypeScript против ES6
TypeScript – это надмножество над стандартами JavaScript – поэтому его синтаксис это кмобинация чистого JavaScript + собственный. Его основная задача – дать строгую типизацию всему – переменным, объектам, классам, интерфейсам, методам и т.д., что поможет избежать множества ошибок на этапе написания кода. (Intellisense и надстройки вроде TSLinter буду ругаться в случае несоответствия каких -либо типов в каком -либо участке кода). В итоге улучшается рабочий процесс разработки.
Некоторые из ключевых особенностей TypeScript включают в себя необязательную статическую типизацию и поддержку интерфейсов, классов и декораторов. (Декораторы — это функции с префиксом «@» за которыми сразу следует класс, параметр или свойство.)
Теперь подробнее про React. В коде ниже приведена его важная особенность:
Смысл в том, что React, при помощи расширения JSX, позволяет вставлять практически нативную HTML разметку в JavaScript файл. Компиляция JSX в понятный браузеру JavaScript происходит при помощи компилятора Babel.
Код выше сводится к следующему:
В случае, если вам не нравится такой подход, можете использовать React.createElement().
Помимо этого, вместо использования стандартов ES6, вы вольны использовать традиционную форму JavaScript, Но это лишит вас многих полезностей в виде, классов, стрелочных функций, шаблонных литералов, деструкции, использования let и const. Из очевидных минусов – постоянный вызов конструкторов базовых классов внутри обычных, а также отсутствие автоматической привязки методов обработки событий к контексту this (решается использованием стрелочных функций).
Проверка типа в Angular и propTypes в React
Проверка статического типа выполняется во время компиляции. Компилятор предупреждает вас о возможных несоответствиях типов и обнаруживает некоторые ошибки, которые в противном случае оставались бы незамеченными. Кроме того, определение контракта по переменной, свойству или параметру функции может привести к более читабельному и поддерживаемому коду.
Объявления переменных и функций становятся более выразительными, объявляя их типы данных. Вы можете больше узнать о различных примитивных типах данных в документации по TypeScript.
Определение сигнатуры API с помощью интерфейса делает код менее двусмысленным и понятным. Интерфейс служит в качестве краткого руководства по началу работы, которое помогает сразу начать работу с кодом и экономит время, затрачиваемое на чтение документации или фактическую реализацию библиотеки.
Ключевое слово type в TypeScript можно использовать для создания псевдонима для типа. Затем вы можете создавать новые типы, которые являются объединением или пересечением этих примитивных типов.
React имеет ограниченную поддержку проверки типов, потому что базовый ES6 не поддерживает его. Тем не менее, вы можете реализовать проверку типов с помощью библиотеки prop-types, разработанной командой React. Проверка типа props у компонента, чтобы проверить строку, можно сделать так, как показано ниже.
Но prop-types не ограничивается строками, числами и логическими значениями. Вы можете сделать намного больше, как описано в документации библиотеки prop-types. Однако, если вы серьезно относитесь к проверке статического типа, вы должны использовать что-то вроде Flow, который является статической библиотекой проверки типов для JavaScript.
Angular CLI против create-react-app
Первоначально запуск проекта с нуля может показаться забавным. Тем не менее, процесс настройки структуры каталогов, написания шаблона кода для компонентов и получения загрузочного приложения является бесполезным и не очень полезным занятием. Ваша стратегия должна заключаться в том, чтобы как можно быстрее справиться с ним и сосредоточиться на фактической разработке приложения. Благодаря Google и Facebook у вас есть инструменты, позволяющие легко и быстро создавать приложения.
Настройка Angular-CLI для angular и create-react-app для React проста, используя npm.
Чтобы создать новое приложение Angular, вы должны использовать следующую команду:
Но это не так. Команда ng generate позволяет создавать компоненты, маршруты, каналы, директивы и службы.
Angular CLI может сделать гораздо больше, например, создать сборку вашего Angular приложения, команды для запуска модульных тестов и сквозного тестирования. Вы можете узнать больше о всем этом на GitHub.
С другой стороны, create-react-app — официально поддерживаемый способ создания приложения React без каких-либо файлов конфигурации.
$ npm install -g create-react-app
Это должно создать рабочее приложение React со всеми зависимостями Babel и webpack. Вы можете запустить приложение в своем браузере, используя npm start.
Вы можете найти сценарии, доступные для react app в файле package.json.
Связывание данных: двусторонняя привязка и однонаправленная привязка
Связывание данных — это функция, которая позволяет синхронизировать данные между состоянием (моделью) приложения и представлением. В односторонней процедуре привязки данных любое изменение состояния приложения автоматически обновляет представление. Напротив, двусторонняя привязка данных связывает вместе свойства и события под одним объектом, то есть любая модификация модели обновляет представление и наоборот.
В React свойства передаются от родительских к дочерним компонентам, что называется однонаправленным потоком данных или сверху вниз. Состояние компонента инкапсулируется и недоступно для других компонентов, если оно не передается дочернему компоненту в качестве props, то есть состояние компонента становится props дочернего компонента.
Но что, если вам нужно распространять данные через дерево компонентов? Это делается через дочерние события и родительские обратные вызовы. Документация React включает хороший пример, который касается такого сценария.
Методы привязки данных, доступные в Angular, относятся к нескольким функциям, которые делают этот процесс интересным. Angular имеет встроенную поддержку для интерполяции, односторонней привязки, двусторонней привязки и привязки событий.
Интерполяция — это самый простой способ привязать свойство вашего компонента внутри текста между вашими тегами HTML и назначением атрибутов.
<p>Welcome back {{currentUser.name}}!
Связывание свойств аналогично интерполяции в том смысле, что вы можете привязать свойства ваших элементов представления к свойствам компонента. Связывание свойств способствует обмену компонентами и идентично тому, как props передается в React.
<img [src] =»userImgUrl»>
<user-child [user]=»currentUser»></ user-child>
Связывание событий позволяет передавать поток данных в противоположном направлении, то есть от элемента к компоненту. Здесь click — это целевое событие, а справа — метод onSave(), который вызывается при возникновении события.
<button (click)=»onSave()»>Сохранить
Но наиболее важной особенностью является двусторонняя привязка с использованием [(ngModel)]. Это объединяет связывание свойств и привязку событий в одной директиве и особенно полезно для форм и полей ввода.
Рендеринг на стороне сервера
Обработка на стороне сервера — традиционная технология рендеринга. Здесь сервер возвращает по запросу весь HTML-файл, а браузер оставляет за собой простое представление его пользователю. С другой стороны, рендеринг на стороне клиента возвращает HTML-документ, таблицу стилей и файл JavaScript.
JavaScript делает последующие запросы для отображения остальной части веб-сайта с помощью браузера. React, Angular и все другие современные интерфейсные библиотеки JavaScript являются хорошими примерами рендеринга на стороне клиента. Это видно, если вы просматриваете исходный код своего Angular/React приложения.
Но рендеринг на стороне клиента имеет недостатки, так как он не очень подходит для SEO и что он возвращает неполный контент HTML, когда вы делитесь своей ссылкой на сайтах социальных сетей. У Angular есть решение под названием Angular Universal, которое позаботится о том, чтобы сделать ваше приложение дружелюбным к поисковым движкам и социальным медиа. Это библиотека, построенная командой Angular, и использование ее определенно будет полезным.
Universal использует технику предварительного рендеринга, когда весь сайт отображается сначала с сервера, а через пару секунд пользователь переключается на рендеринг на стороне клиента. Поскольку все это происходит под капотом, пользователь ничего этого не замечает.
Если вы используете React с Redux, в документации Redux есть хорошее руководство по настройке рендеринга сервера. Вы также можете настроить React для рендеринга с сервера с использованием компонентов BrowserRouter и StaticRouter, доступных в библиотеке react-router. Вы можете узнать больше об этом в этой статье на Medium. Но если вам необходима производительность и оптимизация, вы можете попробовать next.js, который является библиотекой для SSR в React.
Плюсы и минусы Angular
Преимущества Angular:
- Angular используется вместе с Typescript. Он имеет исключительную поддержку для этого.
- Angular-language-service — обеспечивает интеллектуальные возможности и автозаполнение шаблона HTML-компонента.
- Новые функции, такие как generation Angular, использующие библиотеки npm из CLI, generation, и разработка компонентов, использующая Angular.
- Подробная документация, позволяющая разработчику получить всю необходимую информацию, не прибегая к помощи его коллег. Однако это требует больше времени для обучения.
- Односторонняя и двусторонняя привязка данных, что обеспечивает исключительное поведение приложения и сводит к минимуму риск возможных ошибок.
- MVVM (Model-View-ViewModel), которая позволяет разработчикам работать отдельно над одним и тем же разделом приложения, используя один и тот же набор данных.
- Внедрение зависимостей от компонентов, связанных с модулями и модульностью в целом.
- Структура и архитектура, специально созданные для большой масштабируемости проекта.
- Инструменты для условных операторов, циклов прямо в шаблоне
- Контейнеры, шаблоны для отображения условных представлений, а также переиспользуемого контента
- Большой набор стандартных пайпов, что лишает необходимости писать дополнительные функции для приведения данных к нужному виду в template-циклах
- Возможность писать директивы, для расширения базовой функциональности DOM элементов
- Возможность прокинуть исходные данные в дочерний компонент при помощи @Input, а затем получить обработанный результат при помощи @Output
- Большое количество разнообразных функций
- Функции взаимозависимы
- Информацию можно получать напрямую, а не через третьих лиц
- Представлена возможность работать отдельно в одном разделе программы, используя имеющиеся данные
Недостатки Angular:
- Разнообразие различных структур (Injectables, Components, Pipes, Modules и т. д.) усложняет изучение по сравнению с React и Vue.js, у которых есть только «Component».
- Относительно медленная производительность, учитывая различные показатели. С другой стороны, это можно легко решить, используя так называемый «ChangeDetectionStrategy», который помогает вручную контролировать процесс рендеринга компонентов.
- Ошибки во время миграции между версиями
Плюсы и минусы React
Преимущества React:
- Легко изучить, благодаря простому дизайну, использованию JSX (HTML-подобный синтаксис) для шаблонов и очень подробной документации. Разработчики тратят больше времени на написание современного JavaScript и меньше беспокоятся о коде, специфичном для фреймворка.
- Очень быстрая, благодаря реализации React Virtual DOM и различным оптимизациям рендеринга.
- Отличная поддержка рендеринга на стороне сервера, что делает его мощной платформой для контент-ориентированных приложений.
- Первоклассная поддержка Progressive Web App (PWA) благодаря генератору приложений `create-react-app`.
- Привязка данных является односторонней, что означает меньше нежелательных побочных эффектов.
- Redux, самая популярная платформа для управления состоянием приложений в React, ее легко учить и использовать.
- React реализует концепции функционального программирования (FP), создавая простой в тестировании и многократно используемый код.
- Приложения могут быть созданы с помощью TypeScript или Facebook’s Flow, имеющими встроенную поддержку JSX.
- Переход между версиями, как правило, очень прост: Facebook предоставляет «кодовые модули» для автоматизации большей части процесса.
- Навыки, полученные в React, могут быть применены к разработке на React Native.
- Чрезвычайная гибкость приложения.
- Приложение выдерживает большие нагрузки.
- Обеспечивает неизменность родительских данных.
- Гибридные мобильные приложения на React внешне почти не отличаются от нативных.
Недостатки React:
- React не однозначен и оставляет разработчикам возможность выбирать лучший способ развития. Это может быть решено сильным лидерством проекта и хорошими процессами.
- Сообщество делится по способам написания CSS в React, которые разделяются на традиционные таблицы стилей (CSS Modules) и CSS-in-JS (т.е. Emotion и Styled Components).
- React отходит от компонентов на основе классов, что может стать препятствием для разработчиков, которым более комфортно работать с объектно-ориентированным программированием (ООП).
- Смешивание шаблонов с логикой (JSX) может сбить с толку некоторых разработчиков при первых знакомствах с React.
Чем действительно хорош React, и чем он лучше Angular с точки зрения производительности – это Virtual DOM. Если вы не в курсе, что это такое, давайте разбираться.
Задача
Предположим, вы хотите обновить дату рождения пользователя внутри блока HTML-тегов.
Виртуальный DOM обновляет требуемую часть, сравнивая различия между предыдущей и текущей версией HTML-тегов, пока не достигнет даты рождения.
Обычный DOM – будет обновлять всё дерево HTML-тегов пока не достигнет даты рождения.
Почему это важно?
Это может не иметь значения для проблемы, описанной выше. Однако если мы имеем дело с 20-30 асинхронными запросами данных на одной странице (и для каждого запроса мы заменяем весь блок HTML), это повлияет на производительность, а также на впечатление пользователей.
Но сначала, немного истории…
История
Мы не будем вдаваться в подробности того, что именно произошло между Angular и AngularJS: есть много ресурсов, описывающих этот момент. Если вкратце, то Google заменили AngularJS, в котором представления, контроллеры и модели хранились отдельно, на Angular, который стал использовать компонентный подход, как в React, а JavaScript на TypeScript.
В те дни (с ES4 / ES5) изучение JavaScript было очень затруднительным. Если вы приходили из мира Java, C# или C++, мира объектно-ориентированного программирования, то изучение JS приносило одни разочарования. Это не потому, что язык был плохо написан, а потому, что у него другое назначение. Он был создан для обработки асинхронной Web-природы – взаимодействие с пользователем, привязка событий, анимации и т. д.
Что используют компании?
React был первоначально разработан компанией Facebook для собственных нужд, оптимизирования и облегчения разработки компонентов. Бытует мнение, что React используется в Facebook чаще, чем Angular в Google.
Итак, кто какую технологию использует?
React
- New York Times
- Yahoo
- Khan Academy
- Codeacademy
- Airbnb
- Asana
- Atlassian
- Intercom
- Microsoft
- Slack
- Storybook
- AirBnb
- Uber
- Netflix
- Dropbox
Angular
- Eat24
- Microsoft
- Autodesk
- MacDonald’s
- UPS
- Cisco Solution Partner Program
- AT&T
- Apple
- Adobe
- GoPro
- Proton Mail
- Clarity Design System
- Upwork
- Freelancer
- Udemy
- PayPal
- Nike
- Telegram
- Weather
- iStockphoto
- AWS
- Crunchbase
- CVS shop
- onefootball
- NBA
- Delta
TypeScript и JavaScript (ES6+)
Сравнивать Angular и React, не фокусируясь на основном языке, было бы неправильно.
Angular | Описание | React |
OOP | Стиль | OOP |
Статическая | Типизация | Динамическая |
Маленькая | Пользовательская база | Большая |
2012 | Релиз | 1995 |
С точки зрения пользовательской базы, JavaScript имеет гораздо больший потенциал. Но TypeScript постепенно наверстывает упущенное и увеличивает количество своих пользователей, поэтому кто знает, что будет через 10-15 лет.
TypeScript был первоначально разработан в октябре 2012 года компанией Microsoft, чтобы сделать JavaScript проще. TypeScript позволяет компилировать свой код в код JavaScript, а также написать, код ES5 в файле TypeScript.
TypeScript обеспечивает плавный переход для программистов с опытом объектно-ориентированного программирования. Важно отметить, что TypeScript был выпущен во времена ES5, и в течение этого времени не стал языком, основанным на классах.
В последние годы JavaScript претерпел множество значительных изменений, таких как модули, классы, операторы распространения, литералы шаблонов и т. д. Это позволяет разработчикам писать декларативный код, работая в духе истинного ОО языка.
Статическая типизация
Статически типизированный язык означает, что вы можете определить тип переменной (строка, число, массив и т. д.). Нужно всегда помнить о типизации. Если вы работаете с большим приложением, вам придется держать в голове все передаваемые аргументы и типы, в противном случае вы можете сломать код.
Статически типизированное свойство
Статически типизированный аргумент
Итого
- React эффективно работает с памятью (virtual DOM).
- React использует JavaScript (ES6), признанный веб-язык с 1995 года.
- Angular использует TypeScript, выпущенный в 2012 году.
- Статически типизированные языки великолепны, но не делают код более надежным.
- Динамически типизированные языки требуют меньше времени для написания и дают больше гибкости для творчества.
- Изучение языка со статической типизацией может оказаться сложной задачей, особенно если вы работаете только с динамически типизированными языками.
- В ES6 реализовано множество замечательных модулей, классов, операторов распространения, литералов, что позволяет писать чистый и структурированный код.
Сравнение полномасштабного, многофункционального фреймворка с надежной библиотекой пользовательского интерфейса может показаться нецелесообразным. Тем не менее, они представляют собой передовые технологии JavaScript, используемые для создания интерактивных одностраничных приложений, и в этой связи эта статья поможет вам решить выбрать один из них.