yo-yo.js
yo-yo/bel/morphdom
yo-yo and bel are related libraries.
Yo-yo used hyperx and morphdom.
Morphdom: dom diffing with real DOM nodes
So it's like React but uses the real DOM. In their performance benchmarks, it's just as fast as React. (my note: the secret to its speed is that it only reads those DOM properties that don't trigger a reflow, so it can be quite fast)
- faster in some cases than a virtual dom
- interop with vanilla DOM modules
##Demo
Note: In the repo, this has been refactored to use choo
// **** yo.js ****
var html = require('yo-yo')
var n = 5
console.log(html`<div>
<h1>${n}</h1>
</div>`
// for NodeJS ↴
.toString())
When you run this ($ node yo.js
) in NodeJS you get a fake DOM tree.
so you can add .toString
in the end to visualise the result.
So now you have server side rendering!
If want to make it work in a real browser:
// **** yo.js ****
var html = require('yo-yo')
var n = 5
// **** 2. add a root element ↴
var root = document.body.appendChild(document.createElement('div')) // appendChild will return the element appended
// **** 1 use html update ↴
// need a root element to do the diffing on
html.update(root, html`<div>
<h1>${n}</h1>
</div>`)
Then he runs $ budo yo.js
budo
will run the code in a browser with a web server. $ npm install -G budo
It runs browserify as well.
##Modifying state
// **** yo.js ****
var html = require('yo-yo')
var n = 5
var root = document.body.appendChild(document.createElement('div'))
// **** 2. run update first time the page loads ↴
update()
// **** 3. create a timer that updates the state ↴
setInterval(function () {
n++
// then call the update to re-render
update()
}, 1000)
// **** 1. wrap it ↴
function update () {
html.update(root, html`<div>
<h1>${n}</h1>
</div>`)
}
You can also have events hooked up,instead of the setInterval
// **** yo.js ****
var html = require('yo-yo')
var n = 5
// **** 2. add the counter ↴
var x = 0
var root = document.body.appendChild(document.createElement('div'))
update()
setInterval(function () {
n++
update()
}, 1000)
function update () {
html.update(root, html`<div>
<h1>${n}</h1>
// **** 1. ↴
add the coaddunter display
<div>${x}</div>
// add the button ↴
<button onclick=${onclick}>CLICK ME</button>
</div>`)
// **** 3. add the handler here ↴
function onclick (ev) {
x++
update()
}
}
The final refactored code on GitHub:
// **** yo.js ****
var choo = require('choo')
var html = require('choo/html')
var wsock = require('websocket-stream')
var split = require('split2')
var to = require('to2')
var stream = wsock('ws://' + location.host)
var app = choo()
app.route('/', function (state, emit) {
return html`<body>
<h1>${state.visitors}</h1>
<div>${state.x}</div>
<button onclick=${onclick}>CLICK ME</button>
</body>`
function onclick (ev) {
emit('increment-x')
}
})
app.mount('body')
app.use(function (state, bus) {
stream.pipe(split()).pipe(to(function (buf, enc, next) {
bus.emit('set-visitors', Number(buf.toString()))
next()
}))
})
app.use(require('./reduce.js'))