React without observables
by Michel Weststrate
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/JSXTransformer.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/react-with-addons.js"></script>
<script src="https://rawgit.com/mweststrate/MOBservable/master/dist/mobservable.js"></script>
<script src="https://facebook.github.io/react/js/jsfiddle-integration.js"></script>
<div id="container">
<div id="header">
<h1>React shopping cart demo without observables</h1>
<a href="https://www.mendix.com/tech-blog/making-react-reactive-pursuit-high-performing-easily-maintainable-react-apps/">Blog post explaing React + observables</a>
<a href="https://github.com/mweststrate/mobservable">Github repo</a>
</div>
<div id="mount"></div>
</div>
CSS
body {
font-family: 'Georgia';
background: #555;
background-size: cover;
}
h1 {
font-family: 'Arial Black';
}
h2 {
font-family: 'Arial Black';
font-size: 12pt;
}
#header {
text-align: center;
}
#container {
margin-left: auto;
margin-right: auto;
margin-top: 40px;
width: 800px;
padding: 40px;
border-radius: 20px;
background:rgba(255,255,255,1);
box-shadow: 3px 3px 5px 0px rgba(50, 50, 50, 0.7);
}
#container table {
width: 100%;
}
#container table td {
width: 50%;
vertical-align: top;
padding: 20px;
}
ul {
list-style: none;
padding-left: 0px;
}
li {
display: inline-block;
width: 100%;
border-bottom: 1px solid #e2e2e2;
padding: 10px 0;
}
button {
float: right;
margin: 0px 5px;
}
.price {
float: right;
font-style: italic;
margin-right: 10px;
}
.logview {
background-color: #e2e2e2;
font-size: 10pt;
color: black;
padding: 10px 40px;
}
JavaScript 1.7
var autoNumber = 0;
/**
* Data model
*/
function Article(name, price) {
this.id = ++autoNumber; // UUID for this article
this.name = name;
this.price = price;
}
function ShoppingCartEntry(article) {
this.id = ++autoNumber; // UUID for this entry
this.article = article;
this.amount = 1;
}
ShoppingCartEntry.prototype.price = function() {
return this.article ? this.article.price * this.amount : 0;
};
function ShoppingCart() {
this.entries = [];
}
ShoppingCart.prototype.total = function() {
return this.entries.reduce(function(sum, entry) {
return sum + entry.price();
}, 0);
};
// Some available articles
var articles = [
["Funny Bunnies", 17.63],
["Awesome React", 23.95],
["Second hand Netbook", 50.00]
].map(function(e) {
return new Article(e[0], e[1]);
});
// Our shopping cart
var shoppingCart = new ShoppingCart();
// With a demo item inside
shoppingCart.entries.push(new ShoppingCartEntry(articles[0]));
/**
* UI logic
*/
var onRefresh;
// helper function to repaint the whole UI
function updateUI() {
onRefresh();
}
var ShopDemoView = React.createClass({
componentDidMount: function() {
onRefresh = this.forceUpdate.bind(this);
},
render: function() {
return (<table>
<tr>
<td colSpan="2">
<button onClick={this.update}>update some items</button>
<button onClick={this.generate}>create a lot of items</button>
...