Mithril.js: Re-using hyperscript nodes leads to wrong updates on m.redraw()

Created on 25 Jun 2019  路  6Comments  路  Source: MithrilJS/mithril.js

All 6 comments

@dvdkhlng did you try adding a key attribute, like this.queue.push(m("p", {key: Date.now()}, this.count.toString()))?

@osban: you are right, adding a key attribute fixes (or works around) the issue:
https://jsfiddle.net/q0Layhw8/1/

Does this have any effect on the validity of the bug report? I'm a little lost, the Mithril manual does not have any example code that keeps around references to nodes to be returned in view().

@dvdkhlng Not a bug, but undefined behavior. When you're mutating this.queue, that's being returned as a literal fragment vnode, roughly equivalent to m.fragment({}, this.queue). Mithril uses this.queue directly as the children of interest, and mutating that counts as mutating a mutable vnode. To clarify how the docs apply here:

Vnodes are supposed to represent the state of the DOM at a certain point in time. Mithril's rendering engine assumes a reused vnode is unchanged, so modifying a vnode that was used in a previous render will result in undefined behavior.

(Emphasis here, not in docs)

If you really want this behavior, add keys to all the vnodes in question and then return this.queue.slice() instead. That way, Mithril will at least know identities moved around. But in either case, don't do this. Just generate the vnodes as you need them and use keys as necessary.

@dvdkhlng If possible in your case, you could do something like this, so instead of working with vnodes, work with data.

@isiahmeadows : modifying queue after I gave it to Mithril was something that I totally overlooked. Ouch. Javascript semantics take some time to getting used to...

@osban, yes will move to working on data instead of nodes.

thanks for your helpful comments.

@dvdkhlng

modifying queue after I gave it to Mithril was something that I totally overlooked. Ouch. Javascript semantics take some time to getting used to...

Mithril is rather unique among vdom implementations in that it mutates the vnodes it receives. So don't worry, especially if you're coming from a different virtual DOM framework like React. (I didn't make that design choice, BTW.)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

isiahmeadows picture isiahmeadows  路  4Comments

ozgurrgul picture ozgurrgul  路  3Comments

pygy picture pygy  路  3Comments

simov picture simov  路  4Comments

omenking picture omenking  路  3Comments