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.

Deliberate breaking change in render() ?

See original GitHub issue

I 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:open
  • Created 4 years ago
  • Reactions:1
  • Comments:12 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
mindplay-dkcommented, Jun 20, 2019

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.

0reactions
rejhgadellaacommented, Dec 31, 2021

+1. Also seeing the behavior localjo is describing

// Get the parent
const parent = document.getElementById('app');

// Create and append target so we can replace it
const target = document.createComment('I have a target on my back');
parent.appendChild(target);

// Render Component, replacing target
render(<Component />, parent, target);

Result:

<div id="app">
  <div class="Component"></div>
  <!-- I have a target on my back -->
</div>

I solved it by removing target after the render():

// Render Component, replacing target
render(<Component />, parent, target);

// Remove the target because preact prepends Component, leaves target in the DOM.
target.remove();

Maybe the docs and especially the replaceNode argument name are a bit misleading? It says it uses replaceNode to determine where to start rendering, not that it actually replaces anything:

If the optional replaceNode parameter is provided, it must be a child of containerNode. Instead of inferring where to start rendering, Preact will update or replace the passed element using its diffing algorithm.

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

Read more comments on GitHub >

github_iconTop Results From Across the Web

Breaking change in v7 - componentDidUpdate order #1432
We are running into some difficulty updating to v7 due to what seems like a breaking change. Context: We're rendering react inside a...
Read more >
Can only intentionally re-render an entity with references 20 ...
A new _render_path property joins _referringItem on entities when rendered by the entity reference formatter. Data model changes. None. Comment ...
Read more >
5 things not to do when building React applications
But when you are using closures inside the render() method, it's actually bad. Every time the SayHi component renders, a new anonymous function ......
Read more >
Strict Mode - React
Like Fragment , StrictMode does not render any visible UI. ... findDOMNode can also be used on class components but this was breaking...
Read more >
Migrating Breaking Changes in SvelteKit - Netlify
svelte has gone away in favor of +page.svelte to indicate you are deliberately creating a route. You also no longer need the underscore,...
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