Since DOM manipulations are slow, React replicates the DOM virtually. Your application talks to the virtual DOM that is very fast, and then React diffs the virtual DOM with the real DOM and applies all changes efficiently.
Forcing to component structure
var HelloMessage = React.createClass({
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
React.render(
<HelloMessage name="John" />,
document.getElementById('container')
);
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
React.render(
<HelloMessage name="John" />,
document.getElementById('container')
);
React Components are not Web Components because React is abstracted away from browser while Web Components will be a native browser feature.
whenever anything changed that was of interest by the view, just re-render the view. Hey, that’s rather inefficient, isn’t it? Rewrite the whole view when I just need to modify a single span tag?
TODO MVC
React & Backbone.js
<div class="view" data-reactid=".0.1.1.$295dbb7f-5a48-4cca-88ce-4fcf9bffda61.0">
<input class="toggle" type="checkbox" data-reactid=".0.1.1.$295dbb7f-5a48-4cca-88ce-4fcf9bffda61.0.0">
<label data-reactid=".0.1.1.$295dbb7f-5a48-4cca-88ce-4fcf9bffda61.0.1">lllll</label>
<button class="destroy" data-reactid=".0.1.1.$295dbb7f-5a48-4cca-88ce-4fcf9bffda61.0.2"></button>
</div>
All properties are hidden
.jsx
mixing js and html content
/** @jsx React.DOM */
ProfileView = React.createClass({
render: function() {
return (
<div>
<div className="avatar-container">
<AvatarView model={this.getModel()} />
</div>
</div>
);
}
});
ProfileView = React.createClass({
render: function() {
return (
<div>
<div className="avatar-container">
<AvatarView model={this.getModel()} />
</div>
</div>
);
}
});
So see, this diagram is totally unidirectional - actions talk to dispatchers, dispatcher talks to store and views talk to actions! Now I won't be arrested to a callback cascade or something. Every time my view needs something, it will ask for an action, and not lock the controller layer. The dispatcher will handle the invokes.
pretty more complicated than Backbone or Ember. However, it's a very interesting tool IMHO! It brings a very decoupled model, and also seems easy to maintain the code
TEST:
Framework
|
Net Size
|
Size with required dependencies
|
AngularJS 1.2.22
|
39.5kb
|
39.5kb
|
Backbone.js 1.1.2
|
6.5kb
|
43.5kb (jQuery + Underscore)
20.6kb (Zepto + Underscore)
|
Ember.js 1.6.1
|
90kb
|
136.2kb (jQuery + Handlebars)
|
Underscore 9K
from 2010
Backbone.js is basically an uber-light framework that allows you to structure your Javascript code in an MVC(Model, View, Controller) fashion where...
Model is part of your code that retrieves and populates the data VO (Value Object)
this.model.on('change', this.render, this);
Collection (array of Models)
View is the HTML representation of this model(views change as models change, etc)
- jQuery will take care of most of your dom manipulation
- backbone.js will help you organize all of your code and give your js application some structure (mvc pattern)
- underscore.js will give you really useful low-level utility. I would have never needed this library until I really got into js apps (it's also a requirement for backbone.js)
Backbone provides the reusable building blocks loosely following the MVC pattern
Backbone.js & Inheritance http://www.erichynds.com/blog/backbone-and-inheritance
var BaseView = Backbone.View.extend({
// Create a property where we can hold references to subviews
subviews: {}
});
var ContentView = BaseView.extend({
initialize: function() {
this.subviews.sidebar = new SidebarView();
}
});
var HeaderView = BaseView.extend({
initialize: function() {
this.subviews.menu = new MenuView();
}
});
var content = new ContentView();
var header = new HeaderView();
// Create a property where we can hold references to subviews
subviews: {}
});
var ContentView = BaseView.extend({
initialize: function() {
this.subviews.sidebar = new SidebarView();
}
});
var HeaderView = BaseView.extend({
initialize: function() {
this.subviews.menu = new MenuView();
}
});
var content = new ContentView();
var header = new HeaderView();
Backbone View: Inherit and extend events from parent
Template system:
<!-- index.html -->
<script type="text/template" id="pod">
<h2><%= title %></h2>
<p><%= body %></p>
</script>
<script src="view.js"></script>
<script type="text/template" id="pod">
<h2><%= title %></h2>
<p><%= body %></p>
</script>
<script src="view.js"></script>
// view.js
var View = Backbone.View.extend({
template: _.template($("#pod").html())
});
var View = Backbone.View.extend({
template: _.template($("#pod").html())
});
In an external file, loading over network, with dependency management utilities such as requireJS
<!-- pod.html -->
<h2><%= title %></h2>
<p><%= body %></p>
<h2><%= title %></h2>
<p><%= body %></p>
// view.js
define(["text!templates/pod.html"], function(pod) {
var View = Backbone.View.extend({
template: _.template(pod)
});
});
define(["text!templates/pod.html"], function(pod) {
var View = Backbone.View.extend({
template: _.template(pod)
});
});
3. In our view declaration, as a string.
// view.js
var View = Backbone.View.extend({
template: _.template('\
<h2><%= title %></h2>\
<p><%= body %></p>\
')
});
var View = Backbone.View.extend({
template: _.template('\
<h2><%= title %></h2>\
<p><%= body %></p>\
')
});
Backbone does not provide structure. It rather provides some basic tools you can use to create structure, leaving it up to the developer to decide how to structure his application,
Routes:
define(function() {
| |
return Backbone.Router.extend({
| |
routes: {
| |
'lists/:id': 'openList'
| |
},
| |
initialize: function() {
| |
},
| |
openList: function(id) {
| |
if (bTask.collections.lists && bTask.collections.lists.length) {
| |
var list = bTask.collections.lists.get(id);
| |
if (list) {
| |
list.trigger('select');
| |
} else {
| |
console.error('List not found:', id);
| |
}
| |
}
| |
}
| |
});
| |
});
|
Organizing your application using Modules
Backbone.js Application Walkthrough Part 5: RequireJS
<script data-main="src/config/config" src="libs/require.js"></script>