已經用AngularJS了,為什麼要React

AngularJS directives 用來延伸 HTML DOM 有點複雜,那React有甚麼特點呢?

  • React isn’t an MVC framework : 是個 View 的庫
  • React doesn’t use templates : 可以用 JSX,看起來很像 XML 的Javascript
  • Reactive updates are dead simple : 用了才知道…

AngularJS app 整合 React

文章來源Adding ReactJS to an existing AngularJS app with Grunt workflow

首先有講到關於 The more data bindings you have, the longer this digest cycle takes. So if we can reduce or eliminate certain data bindings, then our app should perform better. This is where React can help…

步骤 :

Install ReactJS into my app

bower install --save react

Install grunt-react

在 Build 過程把 JSX 轉譯成 Javascript

npm install --save-dev grunt-react

Hello World JSFiddle

react components 我放的位置: vim app/scripts/components/hello.js

var Hello = React.createClass({
    displayName:'Hello',
    render:function(){
        return React.createElement("div", null, "Hello ", this.props.name);
    }
});

vim index.html

+    <script src="bower_components/react/react.js"></script>

+    <script src="scripts/components/hello.js"></script>

angularjs directive

.directive('helloNg', function(){
    return{
        restrict:'E',
        scope:{
            name:'='
        },
        link:function(scope, el, attrs){
            scope.$watch('name', function(newValue, oldValue){
            React.render(
                React.createElement(Hello, {name:newValue}),
                el[0]);
            })
        }
    }
})

angularjs controller

$scope.name = 'World';

angularjs view

找個地方擺 hello-ng

<hello-ng name="name"></hello-ng>

Hello World with JSX

vim jsx/hello.jsx

var Hello = React.createClass({
    render: function() {
        return <div>Hello {this.props.name}</div>;
    }
});

修改 index.html

+    <script src="bower_components/react/react.js"></script>

+    <script src="scripts/jsx/hello.js"></script>

Grunt watch

 jsx: {
        files: ['<%= yeoman.app %>/jsx/{,*/}*.jsx'],
        tasks: ['react:files']
      },

Grunt Task

react: {
  files: {
    expand: true,
    cwd: '<%= yeoman.app %>/jsx',
    src: ['**/*.jsx'],
    dest: '<%= yeoman.app %>/scripts/jsx',
    ext: '.js'
  }
}

Build Task

加在 usemin 之前

grunt.registerTask('build', [
  'clean:dist',
  'wiredep',
  'react',
  'useminPrepare',
  'concurrent:dist',
  'autoprefixer',
  'concat',
  'ngAnnotate',
  'copy:dist',
  'cdnify',
  'cssmin',
  'uglify',
  'filerev',
  'usemin',
  'htmlmin'
]);

build:js block in my index.html

<!-- build:js({.tmp,app}) scripts/scripts.js -->
<script src="scripts/jsx/hello.js"></script> <!--在這邊...-->
<script src="scripts/app.js"></script>
<script src="scripts/controllers/main.js"></script>
<script src="scripts/directives/image_preview.js"></script>
<!-- endbuild -->

tutorail

Complementary Tools

react bootstrap

參考