Tungsten & React
The Commons Ideas Behind Tungsten and React
Why React?
Declarative vs Imperative
- Imperative: describing how things work
- Declarative: describing what things look like
In Essence
this.listenTo(this.todos, 'all', this.render); addTodo: function() {
if (this.newTodo) {
const todoModel = new Todo({
todo: this.newTodo
});
this.todos.add(todoModel);
}
}In React
Component
setState()
render()
UI = f(state) or UI = f(model)
Declarative Programming Everywhere
Examples
- Mustache Data
- Request Dao
render: function() {
const output = Mustache.render(
mustacheTemplate,
{todos: this.appModel.get('todos').toJSON(), newTodo: this.appModel.get('newTodo')}
);
this.$el.html(output);
return this;
}<div>
<div class="todo_app">
<h1>Todo List</h1>
<ul>
<li><span>grocery shopping</span><input type="checkbox"></li>
<li><span>pay electricity bill</span><input type="checkbox"></li>
</ul>
<input type="text" class="js-new-todo">
<button class="js-add-button">Add Todo</button>
</div>
</div><div>
</div><div>
<div class="todo_app">
<h1>Todo List</h1>
<ul>
<li><span>grocery shopping</span><input type="checkbox"></li>
<li><span>pay electricity bill</span><input type="checkbox"></li>
<li><span>pay phone bill</span><input type="checkbox"></li>
</ul>
<input type="text" class="js-new-todo">
<button class="js-add-button">Add Todo</button>
</div>
</div><div>
<div class="todo_app">
<h1>Todo List</h1>
<ul>
<li><span>grocery shopping</span><input type="checkbox"></li>
<li><span>pay electricity bill</span><input type="checkbox"></li>
</ul>
<input type="text" class="js-new-todo">
<button class="js-add-button">Add Todo</button>
</div>
</div><div>
<div class="todo_app">
<h1>Todo List</h1>
<ul>
<li><span>grocery shopping</span><input type="checkbox"></li>
<li><span>pay electricity bill</span><input type="checkbox"></li>
<li><span>pay phone bill</span><input type="checkbox"></li>
</ul>
<input type="text" class="js-new-todo">
<button class="js-add-button">Add Todo</button>
</div>
</div>VDOM
What's VDOM?
Plain Javascript objects that represents real DOM. Because it's just javascript objects, it's cheap to maintain them in memory.
{ type: ‘ul’, props: { ‘class’: ‘list’ }, children: [
{ type: ‘li’, props: {}, children: [‘item 1’] },
{ type: ‘li’, props: {}, children: [‘item 2’] }
] }<ul className=”list”>
<li>item 1</li>
<li>item 2</li>
</ul>Create real DOM from VDOM
function createElement(node) {
if (typeof node === 'string') {
return document.createTextNode(node);
}
const $el = document.createElement(node.type);
node.children.forEach(childNode => {
$el.appendChild(createElement(childNode));
});
return $el
};The Diffing Algorithm
updateElement($parent, newNode, oldNode, index = 0) {...}The real DOM node where virtual is rendered into
The new virtual DOM node
The old virtual DOM node
The location where virtual DOM node in $parent
The Diffing Algorithm
updateElement($parent, newNode, oldNode, index = 0) {...}1. Only new node at index i - apendChild(...)
2. Only old node at index i- removeChild(...)
The Diffing Algorithm
updateElement($parent, newNode, oldNode, index = 0) {...}3. Different nodes at index i - replaceChild(...)
function changed(node1, node2) {
return typeof node1 !== typeof node2 ||
typeof node1 === 'string' && node1 !== node2 ||
node1.type !== node2.type
}
The Diffing Algorithm
updateElement($parent, newNode, oldNode, index = 0) {...}- Can't tell - call updateElement(...) recursively
Where Virtual DOM is used?
Tungsten
React
JSX
render () {
return (
<ul>
<li>pay bill</li>
<li>buy milk</li>
</ul>
);
}render () {
return React.createElement(
"ul",
null,
React.createElement(
"li",
null,
"pay bill"
),
React.createElement(
"li",
null,
"buy milk"
)
);
}Virtual DOM is fast, so real DOM is slow?
Virtual DOM is much faster than unefficient real DOM manipulation.
Things In Common
- Declarative programming
- Use of irtual DOM
The Differences
Tungstenjs
Model/Collection
View
Template
- stores and manages data (attributes)
- talk to the backend for data persistence
- observes models and updates DOM accordingly
- dispatch DOM events
- defines how the UI look like
Tungstenjs
Model/Collection
View
Template
Model/Collection
View
Template
Child Level
Root Level
...
relations: {
...
}childViews: {
...
}{{ > ... }}React
Child Level
Root Level
...
ParentComponent
ChildComponent
render () {
return (
...
<ChildComponent>
...
);
}Mustache as Templates vs No Templates
Whenever conditions become too complex, it might be a good time to extract a component.
A good rule of thumb is that if a part of your UI is used several times (Button, Panel, Avatar), or is complex enough on its own (App, FeedStory, Comment), it is a good candidate to be a reusable component.
Thank you!
Wayfair React Presentation
By David Zheng
Wayfair React Presentation
Some thoughts about React and frontend in general
- 41