Open yoshuawuyts opened 8 years ago
Hmm let me give it some more thought. Initially it feels like this should be in the diffing library or yo-yo
as bel
doesn't know about previous elements.
Yeah, doesn't thunking only become relevant when you're executing the element creation over and over again (a la morphdom)?
@timwis yeah you're right, but this type of rendering is quickly becoming the default; e.g.
Probably the only hot new one around that doesn't do virtual-dom
diffing would be Angular 2, but that's about it.
Just an update that I've been experimenting with ideas but nothing really to show for yet. But wanted to mention using a feature like this for handling <canvas>
updates.
Currently <canvas>
tags don't work well in the idiomatic flow because the tag never indicates itself as changed. The simple fix would be to always assume a <canvas>
has changed when morphing, replacing with the new one.
But it would interesting if we let the element author choose when to invalidate. Basically the thunk just remembers the last passed arguments/element
and appends to the function. Then any element not marked or first time through the thunk, gets updated. Any previous that are marked will always be ignored:
const html = require('yo-yo')
const thunk = require('yo-yo/thunk')
/* prev arg gets added by thunk to the end of the function call */
module.exports = thunk(function createCanvas (data, prev) {
let canvas = prev.element
if (prev.args[0].width !== data.width || prev.args[0].height !== data.height) {
canvas = html`<canvas width="${data.width}" height="${data.height}" />`
}
const ctx = canvas.getContext('2d')
ctx.fillRect(data.x, data.y, data.width, data.height)
return canvas
})
/* ... */
let data = {x:0,y:0,width:100,height:100}
raf(function loop () {
data.x += .1
if (data.x > 100) data.width *= 2
yo.update(root, canvas(data))
raf(loop)
})
This might simplify the validation check too as we wouldn't need to traverse objects and arrays checking if the arguments have changed. We just let the element author choose the parameters that decide that. Which most of the time would be 1 or 2 if statements.
Or we could provide that API for convenience to the author to apply as needed:
const html = require('yo-yo')
const thunk = require('yo-yo/thunk')
module.exports = thunk(function createMyButton (data, prev) {
let button = prev.element
if (!button || prev.hasChanged(data)) {
button = html`<button>${data.label}</button>`
}
return button
})
That looks awesome @shama! Thanks for the writeup. prev
being an object with element
and args
properties (rather than just the previous version of data
) was confusing at first but I don't have a better idea. Maybe if it were called cache
or something...
If I recall correctly, the way react (or at least redux) handles this is by "mapping state to props" when connecting the store to the component, so that react knows whether to update that specific component on a given state change. Right?
@yoshuawuyts https://github.com/yoshuawuyts/cache-element/ can be used to thunk
element, or am I confused?
Yup, though I recommended nanocomponent these days - iterated on the interface a bit
On Mon, Feb 6, 2017, 23:15 Björn Roberg notifications@github.com wrote:
@yoshuawuyts https://github.com/yoshuawuyts https://github.com/yoshuawuyts/cache-element/ can be used to thunk element, or am I confused?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/shama/bel/issues/40#issuecomment-277831819, or mute the thread https://github.com/notifications/unsubscribe-auth/ACWlerG7SCfNAjUvrJ1sYvee_HIQ_er7ks5rZ5uTgaJpZM4Jbsbi .
In
yo-yo
andchoo
it's a best practice to have element functions in an application return the same element given the same input. This mechanism is commonly referred to asthunking
.How would we feel about adding a light wrapper that exposes a
thunk
function so that elements can be thunked with little effort. I was thinking of an API along these lines:In a
choo
app this could then be consumed as:What do you think? Would this be a useful addition to
bel
, or should we continue to point people to use an external thing / write it themselves? I was thinking of including this intochoo
, but given that we strongly encourage people to usebel
for standalone components (yay, reusability) I figured it might make more sense to include it here first, and then have it propagate upwards throughyo-yo
tochoo
. Thanks!See Also