-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
86 lines (79 loc) · 2.54 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
const html = require('choo/html')
const choo = require('choo')
const app = choo()
app.model({
state: {
count: 0,
toggled: true
},
reducers: {
update: (data, state) => ({ count: state.count + 1 }),
toggle: (data, state) => ({ toggled: !state.toggled })
}
})
const view = (state, prev, send) => {
return (state.toggled)
? html`
<div>
<h1>count: ${state.count}</h1>
<button onclick=${() => send('update')}>Update state</button>
<button onclick=${() => send('toggle')}>Toggle memo</button>
${subView(state, prev, send)}
${memoizedSubView(state, prev, send)}
</div>`
: html`
<div>
<h1>count: ${state.count}</h1>
<button onclick=${() => send('update', 'world')}>Update state</button>
<button onclick=${() => send('toggle')}>Toggle memo</button>
${subView(state, prev, send)}
</div>`
}
function subView (state, prev, send) {
return html`
<div onload=${(el) => console.log('subView loaded')}>
subView
</div>
`
}
// let's create some empty vars we can reference later
let memoizedEl = null
let mounted = false
function memoizedSubView (state, prev, send) {
// the first run we got no memoized el yet. Cool, let's create one
if (!memoizedEl) {
memoizedEl = html`
<div
onunload=${(el) => {
console.log('memoizedSubView unloaded')
mounted = false
}}
onload=${(el) => console.log('memoizedSubView loaded')}>
memoizedSubView
</div>
`
// we're going to be returning this el so it'll also be mounted. Let's mark
// it as such
mounted = true
return memoizedEl
} else if (!mounted) {
// if our node for some reason was unmounted, onunload sets it as
// "unmounted". In that case we just return our unmounted node, and the
// "onload" action will be triggered again
mounted = true
return memoizedEl
} else {
// welp, if our node is mounted, and exists, we return the proxy node. It
// means we can make it pretend like it's the already mounted node so we
// can tell the diffing algorithm to ignore it and not do anything. If we
// didn't pass this, or passed the actual mounted nodes the "onload" and
// "onunload" properties would be fired on every render and that's super
// bad. But yay, we can use this so we do that :D
const placeholder = html`<template></template>`
placeholder.isSameNode = (el) => el.isSameNode(memoizedEl)
return placeholder
}
}
app.router(['/', view])
const tree = app.start()
document.body.appendChild(tree)