Deliberate breaking change in render() ?
See original GitHub issueI noticed an important difference between render()
in Preact 8 vs current beta 10.
With 8.4.2:
https://jsfiddle.net/mindplay/4Lebz2x1/1/
With 10.0.0-beta.2:
https://jsfiddle.net/mindplay/hxnr23jL/5/
As you can see, with the current beta 10, the rendering order is opposite - where Preact 8 would append to existing elements, Preact 10 seems to preprend before existing elements.
The practical use-case that broke here is a pop-up dialog being rendered over an existing page. Where, previously, this would append to the document body, now it’s being prepended, and disappears under headers, background images, ads, etc.
We can control this with z-index of course, but this particular script needs to drop-in and work on different sites with different CSS - so my work-around for now is to emulate the old behavior by manually, e.g.:
render(<...>, document.body.appendChild(document.body.createElement("div"));
No big deal, though I now have an extra wrapper div and/or need to manually initialize the root element (classnames, etc.) of that dialog using DOM methods.
Is this a documented, “by design” change? (why?)
Appending a newly created node seemed more intuitive and practical to me. 🤷♂️
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:12 (2 by maintainers)
I’ve never used React, so compatibility with React isn’t really a good argument from my point of view.
React expects an empty render target - Preact (8) of course allows rendering into an empty target, so it is compatible with React in that sense.
Having the option to render to a target with existing children, from my perspective, is an extra feature - not an “incompatibility”. It’s really convenient when adding dialogs or other interactive content to pages with existing content.
Either way, Preact X should be compatible either with 8.x or React - introducing a third behavior isn’t really meaningful, I think?
My strong preference would be BC with Preact 8.x, as I have a lot of projects based on that, and frequently rely on rendering interactive things into pages with content.
+1. Also seeing the behavior localjo is describing
Result:
I solved it by removing
target
after therender()
:Maybe the docs and especially the
replaceNode
argument name are a bit misleading? It says it usesreplaceNode
to determine where to start rendering, not that it actually replaces anything:https://preactjs.com/guide/v10/api-reference/#render
Or is it possible that Preact doesn’t touch
target
because it’s not part of its virtual DOM?Preact 10.6.4 Preact-cli 3.3.3