AngularJS и ReactJS или как сделать ваше приложение быстрее

от автора

Современный мир программирования, а особенно веб и javascript уже давно не тот и имеет очень большое колличество инструментов для той или иной задачи. В сегодняшнем посте я хотел бы рассказать как скрестить мощь AngularJS и молниеносность отображения view – Facebook React.

Всем известно, что когда мы генерируем коллекцию во view через Angular, то каждый элемент этой коллекции становится observable. Я конечно понимаю и знаю что есть определенный набор библиотек и решений как это обойти, но сегодня речь не об этом. Что же дает нам React? Ну одно из его преимуществ, это jsx синтаксис, который есть не что иным как html в javascript. Также есть возможность создавать reusable компоненты, наследовать их и использовать всю мощь что позволяет делать эта библиотека. Что же приступим.

Первым делом создадим простой проект с банальным названием ng-with-react. Для установки библиотек я воспользуюсь bower. С помощью него установим AngularJS, ReactJS и Twitter bootstrap дабы наше приложение имело хоть какой-то презентабельный вид. Создадим main.js и index.html которые будут иметь код:

<!DOCTYPE html> <html> <head lang="en">     <meta charset="UTF-8">     <title>AngularJS with Facebook react</title>      <link rel="stylesheet" href="app/vendor/bootstrap/dist/css/bootstrap.css"/>      <style>         .user-list .user-item {             border-left: none;             border-right: none;         }         .user-list .user-item:last-child {             border-bottom: none;         }     </style>      <script src="app/vendor/angular/angular.js"></script>     <script src="app/vendor/react/react.js"></script>      <script src="app/main.js"></script>  </head> <body ng-app="app">     <div class="container" ng-controller="MainCtrl as main">          <div class="page-header">             <h1>A experiment with AngularJS and ReactJS</h1>         </div>          <div class="panel panel-default">             <div class="panel-heading">Just AngularJS</div>             <ul class="list-group">                 <li class="list-group-item" ng-repeat="user in users" ng-click="main.getUser(user)">                     {{ user.firstName }} - {{ user.lastName }}                 </li>             </ul>         </div>     </div> </body> </html> 

И

(function(ng, React)      var app = ng.module('app', []);      var UserFactory = function() {         var users = [             {id: 1, firstName: "Denis", lastName: "Stoyanov", age:26},             {id: 2, firstName: "Alex", lastName: "Alexeev", age:24},             {id: 3, firstName: "Peter", lastName: "Petrov", age:21},             {id: 4, firstName: "Ivan", lastName: "Ivanov", age:20}         ];          return {             users: users         };     };      var UserCtrl = function($scope, $log, User) {         $scope.users = User.users;          this.getUser = function(user) {             $log.info('A selected user %O', user);         };     };     app.factory('User', [UserFactory]);      app.controller('MainCtrl', ['$scope', '$log', 'User', UserCtrl]);       return app;  })(angular, React); 

Соответственно.

Что у нас есть в арсенале сейчас. Мы имеем простейшее приложение на ng в котором есть простейший контроллер и сервис, который отдает фейковые данные. На стороне представления мы имеем простейший список, который рендерит наши данные. Также у нас есть обработчик по клику на элемент, который записывает юзера в консоль. Все довольно просто и легко.
Теперь давайте создадим новую директиву для отображения этих же данных, но только через ReactJS. Как подобает в лучших домах Парижа, нам стоит использовать директивы для манипулирования DOM. Для начала создадим React class для рендеринга списка. Его код будет выглядет примерно так:

var UserList = React.createClass({         displayName: "UserList",         render: function() {             var users = this.props.scope.users;             var scope = this.props.scope;              var userList = users.map(function(user, index, array) {                 var clickHandler = scope.$apply.bind(scope,                     scope.userSelected.bind(null, {user: user}));                  return React.DOM.li({ className: "user-item list-group-item", onClick: clickHandler },                     [user.firstName, user.lastName].join(' - '));             });              return React.DOM.ul( {className:"user-list list-group"}, userList);         }     }); 

Как можно заметить в свойствах React есть ряд переменных, которых нам надо будет передать путем простой передачи scope в React class. Также создадим директиву, которая будет использовать этот класс как представление.

var UserDirective = function() {         return {             restrict: 'AE',             scope: {                 users: '=',                 userSelected: '&'             },             link: function(scope, element, attrs) {                 scope.$watchCollection('users', function() {                     React.renderComponent(UserList({scope: scope}), element[0]);                 });             }         };     };      app.directive('userList', UserDirective); 

В ней видно, что будем мы ее использовать как элемент или же аттрибут, в нее будут переданы данные с юзерами и функция для вывода юзера в консоль. Чтобы наше представление отображалось при изменении коллекции и создадим простейший watcher и на его изменения будет перерисовывать наше представление. И наконец мы срендерим наш React class в тот елемент, на который был повешен аттрибут user-list. В index.html после рендеринга на Angular добавим такой код:

        <div class="panel panel-default">             <div class="panel-heading">AngularJS with ReactJS</div>             <div user-list users="users" user-selected="main.getUser(user)"></div>         </div> 

Вот такими простыми манипуляциями мы связали Angular и React. Приложение простейшее, но оно дает понять концепт и в дальнейшем можно усложнять. По моим тестам при 2000 елементов view на React было в 5 раз быстрее чем на Angular.
На скриншоте мы можем видеть, что у view на React нет байндингов в отличии от ReactJS.

Также мы можем посмотреть, что нам сгенерировал React.

Надеюсь мой эксперимент будет кому-то полезен. Я считаю, что надо компоновать решения по их возможностям и если писать на ReactJS представления удобней и в отображении они быстрее, то я буду делать так.
Если есть каки-то нюансы, welcome в комментарии =)

ссылка на оригинал статьи http://habrahabr.ru/post/215607/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *