React is a JavaScript library to build reusable UI components
Build encapsulated components that manage their own state
Compose them to make complex UIs
Component logic is written in JavaScript instead of templates
React provides a declarative library that keeps the DOM in sync with your data.
Design simple views for each state in your application
React will efficiently update and render just the right components when your data changes
Declarative views make your code more predictable and easier to debug
Create lightweight description of component UI
Diff it with the old one
Compute minimal set of changes to apply to the DOM
Batch execute all updates
Clear, declarative programming model
Optimized DOM updates and less reflows
var Header = React.createClass({
render: function () {
return (
<h1>Order header</h1>
);
}
});
Rendered to JavaScript, not HTML!
"use strict";
var Header = React.createClass({
displayName: "Header",
render: function render() {
return React.createElement(
"h1",
null,
"Order header"
);
}
});
var Header = React.createClass({
render: function () {
return (
<h1>Employee Directory</h1>
);
}
});
return React.createClass({
/*
...
*/
render: function () {
return (
<div className="react-order-list">
{ this.props.orders.map(function (group) {
return (
<div key={ group.index }>
<LabelLine ordergroup={ group }/>
<OrderRows orders={ group.orders } toggleDetails={ toggleFn }
openRow={openRow} searchTerm={ searchTerm }/>
</div>
)
})}
</div>
);
}
});
Properties passed by the parent are available in this.props in the child
Text
return (
<LabelLine ordergroup={ group }/>
<OrderRows orders={ group.orders }/>
)
Text
var LabelLine = React.createClass({
render: function () {
return (
this.props.ordergroup.orders.length ?
<h4 className="in-table-heading mb-capitalized">
{ this.props.ordergroup.label }
</h4> : null
);
}
});
Pass event handler as a property
var OrderRows = React.createClass({
render: function () {
var toggleFn = this.props.toggleDetails;
return (
<div>{ this.props.orders.map(function (order) {
return <OrderRow order={order} key={ order.orderId }
toggleDetails={ toggleFn } />
})}</div>
)
}
});
var OrderRow = React.createClass({
toggleDetails: function () {
this.props.toggleDetails(this.props.order.orderId);
},
render: function () {
return (
<div className={ rowStyle } data-layout-wrap tabIndex="30"
onClick={ this.toggleDetails } >
/*...*/
}
});
We are able to bypass rendering (and calling superExpensiveFunction) when it isn't needed
shouldComponentUpdate: function (nextProps) {
return nextProps.openRow != this.props.openRow;
}
Greater performance than Angular can offer (two way data binding, Object.observe, too many scope watchers on the page) and React is typically more performant due to the Virtual DOM and other optimizations it can make
Angular directive that delegates off to a React Component
<div class="div-table" data-ng-if="vm.items.length && !vm.loading"
data-mb-react-order-list data-orders="vm.items"
data-selected-order-fn="vm.setSelectedOrder"
data-selected-order="vm.selectedOrder"
data-send-order-email-fn="vm.sendEmail"
data-search-term="vm.appliedFilter.searchTerm"
data-watch-depth="collection">
</div>
angular.module('mb2App.directives')
.directive('mbReactOrderList', function (reactDirective) {
'use strict';
return reactDirective('ReactOrderListFactory', undefined, {
restrict: 'A'
});
});
angular.module('mb2App.orderHistory.services')
.factory('ReactOrderListFactory', function ($rootScope, $state, $filter) {
...
return React.createClass({
render: function () {
...
}
});
});