Rendering directly to a DOM element
See original GitHub issueI wonder why it is that render()
accepts a VNode and a parent, rather than a target element?
It’s inconsistent with how the diff()
function works internally, and in some situations, this means you’re forced to create a dummy parent wrapper-element, just to control where in the DOM your rendered elements end up.
While, in the case of simply adding an view to document.body
, it’s perhaps convenient to have render()
automatically append to an empty container, it’s not very practical, because the parent/child relationship of the arguments assumes a 1:1 relationship between the root of the component view and it’s parent/wrapper element.
It would be much simpler and more elegant to have the external render()
function work just like the internal diff()
function, in terms of accepting a target DOM node, and the VNode state you’d like it to have.
It’s not like the typical case of appending to document.body
gets a whole lot more complex that way:
render(<App/>, document.body); // now
document.body.appendChild(render(<App/>)); // proposed
This would free us the need for dummy wrapper elements, and provides a lot more flexibility in cases where you have an existing element and want to update it directly.
For example, in this prototype I’m currently re-rendering all of the draggable panels, which are actually unrelated user-interfaces. I’ll eventually change that, so that the panels themselves get created and managed individually, at which point the current API will force me to add a dummy wrapper element around every panel.
That’s no disaster, obviously - it’s just a bit silly, and it’s not how Preact itself works internally in diff()
, so it’s a bit frustrating that convenience has to get in the way of correctness. The fact that the API ends up dictating HTML structure leads to real-world problems when designers deliver HTML and CSS, and a developer ends up having to change the HTML and CSS (and possibly breaking the design) in order to accommodate the framework.
This issue was widely debated here and ultimately lead to a similar API change in that library.
Thoughts?
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:8 (4 by maintainers)
Top GitHub Comments
We can’t render without a parent, because mounting will happen prior to the tree being appended to the DOM.
To render into an empty tree, you can use a DocumentFragment:
We have it this way, because react also does it the same way
Why do you want the panels to be managed outside of preact?
( btw: you should really use
transform: translate(Xpx, Ypx)
+will-change: transform
instead oftop
andleft
)