question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Incorrect procedure during component root element tag change

See original GitHub issue

Sandbox with forgo-state Sandbox without forgo-state

I think this may be what triggered of forgo/forgo-state forgojs/forgo-state#2; this bug was introduced in the same commit mentioned there, and now knowing the more specific cause I can reproduce this bug even after forgo-state@1.1.0.

When a component renders and returns a different root tag than before, the old tag gets marked for unloading but never actually gets cleaned up. So every time the component switches tags, the parentElement’s list of unloadable nodes grows longer an longer.

The next time the parent rerenders, the node gets unmounted, which prompts forgo-state to unbind it from the state. Except the component never gets remounted, so the new element never gets bound back to the state, and it just becomes unresponsive to state changes, while the parent’s unloadable nodes list grows without bound.

Because the new tag got rendered, the UI looks like it’s correct until you try interacting with the updated element. And if you’re not using forgo-state, you might not even notice, since the component holding the new tag can correctly ask itself to rerender. The deletedNodes/unmount part happens even without forgo-state, but things seem like they’re working fine as long as the component doesn’t have an unmount method.

I’m investigating how to fix this, with these goals:

  • Prevent the unloadable nodes list from growing unboundedly
  • Stop unmounting the component just because its tag changed

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
jeswincommented, Apr 17, 2022

PR for your review - #48

1reaction
spiffytechcommented, Apr 14, 2022

The bogus unmount happens in the sandbox when the parent rerenders before the child. Forgo is getting confused because renderExistingElement() is unloading nodes on targetElement, when it needs to be unloading on targetElement.parentElement. I.e., when the parent rerenders, forgo compares the parent’s component against the childrens’ components list, and inevitably decides to discard the children states because none of them match the parent. But if the child rerenders first, deletedNodes is empty, and that code path isn’t triggered.

I tried changing which element gets unloaded, which fixes the unmount, but then the parent’s deletedNodes starts growing again. I fixed that with an extra unloadMarkedNodes() call in renderComponentAndRemoveStaleNodes(), which fixes the issues in the sandbox, but now a handful of tests about keyed components fail.

I need to check those failing tests and see whether I need a different approach to tackle this bug.

Read more comments on GitHub >

github_iconTop Results From Across the Web

enable <template> as component root element when it ...
So I can't use <template> as component root element even if it contains only one node.
Read more >
xml - How to fix error: The markup in the document following ...
This error indicates that your XML has markup following the root element. In order to be well-formed, XML must have exactly one root...
Read more >
JAXB Users Guide - Java EE
This document explains various interesting/complex/tricky aspects of JAXB, based on questions posted on the JAXB users forum and answers I provided.
Read more >
5. Working with the Shadow DOM - Modern JavaScript [Book]
Creating a shadow root is a straightforward process. First a shadow host node is selected, and then a shadow root is created in...
Read more >
Chapter 17 Binding between XML Schema and Java Classes
Process content: The client application can modify the XML data represented by the ... When XML element information can not be inferred by...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found