Three patterns — which ones work and why.
The reconciler renders a <div> and holds a useRef to it.
A useEffect mounts a Vertex.template into that div.
The reconciler owns the wrapper node; the template owns only the innerHTML
inside it. They never touch each other's DOM.
Data flows reconciler → template by calling tmpl.update()
inside an effect whenever state changes. Data flows template → reconciler
via the template's on('change', …) event, which calls a setState
dispatcher. Fully bidirectional.
The reconciler and template live in completely separate DOM regions.
A plain JS object acts as the shared store. When either side mutates it,
the other is notified via a tiny event emitter — no framework coupling at all.
The template calls tmpl.update(store); the reconciler calls
its setState dispatcher.
If a template renders a <div id="sub"> and you call
Vertex.render(component, subDiv) into it, the next time the
template calls this._el.innerHTML = … it destroys every DOM node
the reconciler placed inside it. The reconciler's fiber.dom
references now point to detached, garbage-collected nodes.
The reconciler doesn't know this happened — it will continue patching ghost nodes
that are no longer in the document, silently producing no visible output.
The template's innerHTML = is a full DOM nuke. Any foreign state
(reconciler fiber tree, third-party widgets, canvas contexts) inside that element
is irrecoverably lost.