React & Virtual DOM
Swarup Karavadi
@swazza85
diff-patch-apply
What is Virtual DOM
- A tree data structure that represents a View at any given point in time.
- Introduced by ReactJS.
ReactJS
- Framework created by Facebook.
- Facebook wanted to build a UI framework that would
- Allow for greater "composability".
- Minimize side effects of mutations.
Mutations
- Mutation === change
- Mutations are directional
- Can be data => view (ex - receive ajax response and update view)
- Can be view => data (ex - user interactions resulting in model updates)
- Mutations have side effects
- Bi-directional mutation === two way data binding
- Side effects of bi-directional mutations are not trivial to reason about
Mutation Side Effects
{0} $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations: {1}
- How often have you come across code like this?
- How much time have you spent debugging trying to find what caused the digest cycles to go into an infinite loop?
- What if you could make your code easier to reason about?
- Enter Uni-directional data-flows
ReactJS and Uni-directional dataflow
- Mutations flow from data to the view
- Any user interactions do not directly alter model data
- User interactions are communicated to interested parties via custom events
- How would you implement this -
Angular Example
- The 'span' element has no control over when it's value changes.
- The 'span' element's state change is driven from external factors.
The React Way
- The 'span' component has complete control over its state.
- It has explicit control on when it would like to update its state by subscribing to interesting events.
- Self contained component
- Easier to reason about
- Basis of Flux architecture
Time for some Code
var ee = new EventEmitter()
var reactInput = React.createClass({
getInitialState: function () {
return { value: "" };
},
onInputChange: function(e) {
var newValue = e.target.value;
el.setState({value: newValue});
ee.emitEvent('valueChanged', [newValue]);
},
render: function() {
return React.createElement("input", { type: "text", onChange: this.onInputChange, value: this.state.value })
}
});
var reactSpan = React.createClass({
getInitialState: function () {
return { value: "" }
},
componentWillMount: function () {
ee.addListener('valueChanged', function(newValue) {
el2.setState({ value: newValue });
});
},
render: function () {
return React.createElement("span", null, this.state.value)
}
});
var el = React.render(React.createElement(reactInput), document.getElementById("mountNode"))
var el2 = React.render(React.createElement(reactSpan), document.getElementById("mountNode1"))
Enter the V-DOM
Essence of V-DOM
// Time T0
var tree = render(getData());
var rootNode = createElement(tree);
var vdom = document.getElementById("vdomRoot");
vdom.appendChild(rootNode);
// Time T1
var newTree = render(getData());
var patches = diff(tree, newTree);
rootNode = patch(rootNode, patches);
tree = newTree;
// Time TN
var newTree = render(getData());
var patches = diff(tree, newTree);
rootNode = patch(rootNode, patches);
tree = newTree;
What Next
- https://github.com/Matt-Esch/virtual-dom
- Whole bunch of libraries inspired by V-DOM. Check em out at http://vdom-benchmark.github.io/vdom-benchmark/
- React Native
- Flux Architecture
On a parting note - Angular vs React: Percieved Performance
- Stress test
- Bind data to a 500 row table with 4 columns - 2000 data bindings
- Do this in a setInterval of 0.
Angular
React
The Virtual DOM
By Swarup Karavadi
The Virtual DOM
- 1,424