Mithril.js: redraw() getting called twice in the same tick on unmounting a view

Created on 7 Jul 2017  路  2Comments  路  Source: MithrilJS/mithril.js

moved from #1888. repro: https://jsfiddle.net/qhprw0ku/7/

The exact error is Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is no longer a child of this node. Perhaps it was moved in a 'blur' event handler? I only get an error in Chrome 59, not Firefox 54 or Safari 10.

To reproduce: create an <input>, add onfocus and onblur handlers, that add/remove a keydown event, that triggers a route change.

analysis from @pygy:

it may be due to the fact that m.route calls run directly, and then the onblur event fires and triggers a sync redraw, since redraw is unaware of the run() call

That is fixed in #1592 since run() is only called at mount time. After the first call m.redraw() takes over.

https://github.com/MithrilJS/mithril.js/pull/1592/files#diff-63de04924f7fd5b53de072769e289dfbR17

Bug

All 2 comments

The sequence is:

  • m.route.set() => schedule a route change.
  • route resolution machinery => direct call to m.render() (through run()) => remove the input, trigger onblur => causes a redraw() with calls m.render() synchronously as the previous call hasn't returned.

Nested render() calls on the same root === sadness.

No longer throwing errors in mithril@next.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

millken picture millken  路  4Comments

omenking picture omenking  路  3Comments

raykyri picture raykyri  路  4Comments

hadihammurabi picture hadihammurabi  路  4Comments

pygy picture pygy  路  4Comments