Sneaking React into Angular (again)

Who am I?

  • Josh Finnie (@joshfinnie)
  • Senior Software Maven @ TrackMaven
  • NodeDC co-Organizer
  • Lover of JavaScript
  • Coder of Python (and CoffeeScript)

ngReact

There's a package called ngReact that does this for us, I just wanted to try from scratch!

ngReact

/** @jsx React.DOM */
var HelloComponent = React.createClass({
  propTypes: {
    fname : React.PropTypes.string.isRequired,
    lname : React.PropTypes.string.isRequired
  },
  render: function() {
    return <span>Hello {this.props.fname} {this.props.lname}</span>;
  }
})

app.value('HelloComponent', HelloComponent);

angular.module('app', ['react'])
  .controller('helloController', function($scope) {
    $scope.person = { fname: 'Clark', lname: 'Kent' };
  });
<!-- ngReact.html -->

<body ng-app="app">
  <div ng-controller="helloController">
    <react-component name="HelloComponent" props="person" watch-depth="reference"/>
  </div>
</body>

Background

  • At TrackMaven, we have a very large Angular.js application (written in CoffeeScript)
  • Angular gives us almost everything we need as a front-end framework.
  • But, could things be better?

Why not React?

Why React.js?

  • React is simple*
  • React's data-flow is clearer to understand
  • And, most importantly, React has easy, composable components!

However

  • We cannot rewrite our whole application
  • We cannot rewrite our whole application
  • And, most importantly, we cannot rewrite our whole application

This lightning talk shows you just that - React component in an Angular application without rewriting our whole app.

angular.module('app', ['ui.router'])

.config(['$stateProvider', function($stateProvider){
    $stateProvider
        .state('base', {
            url: '/',
            templateUrl: 'index.html'
        })
        .state('angular', {
            url: '/angular',
            templateUrl: 'angular.html',
            controller: 'Twitters'
        })
        .state('react', {
            url: '/react',
            templateUrl: 'react.html',
            controller: 'Twitters'
        });
}])

.controller("Twitters", ['$scope', '$http', function($scope, $http) {
    $scope.tweets = []
    $http.get('tweets.json')
        .then(function(res) {
            $scope.tweets = res.data;
        });
}])

Base Angular App

.directive("tweet", function() {
    return {
        restrict: 'E',
        template: `
        <span>
            <p>
                <a href="https://twitter.com/{{tweet.user.sceen_name}}">
                    @{{tweet.user.screen_name}}
                </a> tweeted "<b>{{ tweet.text }}</b>" on {{tweet.created_at}}.
            </p>
        </span>
        `
    }
});

Oldschool NG Directive

<!-- angular.html -->

<span ng-repeat="tweet in tweets">
  <tweet></tweet>
</span>
.directive("reactTweets", function() {
    return {
        restrict: 'E',
        scope: {
            tweets: '=tweets'
        },
        link: function (scope, elem, attrs){
            scope.$watch('tweets', function(newValue, oldValue){
                ReactDOM.render(
                    <Tweets tweets={ newValue } />,
                    elem[0]
                );
            });
        }
    }
});

New React Directive

<!-- react.html -->

<react-tweets tweets=tweets></react-tweets>
var Tweet = React.createClass({
    render: function() {
        return (
            <span>
                <p>
                    <a href="https://twitter.com/{ this.props.tweet.user.sceen_name }">
                        @{ this.props.tweet.user.screen_name }
                    </a> tweeted "<b>{ this.props.tweet.text }</b>" on { this.props.tweet.created_at }.
                </p>
            </span>
        );
    }
});

var Tweets = React.createClass({
    render: function() {
        return (
            <div class="tweets">
                { this.props.tweets.map(function(tweet) {
                    return (
                        <Tweet tweet={ tweet } />
                    )
                })}
            </div>
        );
    }
});

React Components

Demo Time

Why?

  • Interesting in trying React
  • Angular's directives are not the easiest thing to understand
  • Alos, there's a huge negative to using `ng-repeat` over a very complex directive that I think this might solve
  • It seems cleaner to me...

Questions?

Thoughts?

Thanks!

  • Josh Finnie (@joshfinnie)
  • Senior Software Maven @ TrackMaven
  • NodeDC co-Organizer
  • Lover of JavaScript
  • Coder of Python (and CoffeeScript)
  • Docker Aficionado 

Sneaking React into Angular, Again

By Josh Finnie

Sneaking React into Angular, Again

  • 2,951