Preact-cli: Async component mounted/shown twice at same time

Created on 1 Dec 2018  路  21Comments  路  Source: preactjs/preact-cli

I've been working with the preact-cli material template and it seems that a call to setState from within handleRoute of app.js causes the async wrapper's componentWillMount to fire twice, resulting in the async component being duplicated on the screen. (next branch 3.0.0-next.14, but also observed in v2).

This behavior can be seen with npm run serve after running preact-cli create material demo, but the page needs to be scrolled to notice the duplication (I didn鈥檛 notice for some time).

I also have a stripped down repo that minimally reproduces the behavior (without the router nor material design): https://github.com/shalomvolchok/async-route-duplication

In the stripped down repo the behavior is triggered by calling setState from componentDidMount (in any component higher than the async component).

I had to dig for a while before I figured out where the double rendering was coming from, but it鈥檚 still not clear to me what the right solution would be to avoid/fix this. What do you all think?

bug

Most helpful comment

I personally don't think we should be doing this hack, @developit can u check?

All 21 comments

cc @developit i am not sure if this should be fixed in the template or the async wrapper

Just to mention that I'm facing the same issue, going to poke around to see what are the best steps to avoid this.

A quick temporary hack

setTimeout(()=>{this.setState({/*...*/}},0)

Can confirm @shalomvolchok solution works, modifying the default app.js with the following solves the issue for now:

handleRoute = e => {
  setTimeout(() => {
    this.setState({
       currentUrl: e.url
    })
  }, 0)
};

I personally don't think we should be doing this hack, @developit can u check?

cc: @lukeed

the bit that causes the duplication is pretty important, it prevents the first client-side render from ripping out the prerendered DOM. Looks like we just need to synchronously flush via forceUpdate instead of setState.

馃憢 just wanted to share that sadly the hack isn't really working as I thought, and keep getting the issue whenever I prerender it with preact build. Any suggestion on how to be able to serve a preact-cli app statically without having the same component twice.

@developit @ForsakenHarmony could I get more information on what do you think it's causing the issue here or some pointers on where to look? Maybe I can do some work on my own to solve this, as my current site still has this issue and haven't been able to work around it 馃槩

My preact-cli material template on Netlify renders duplicate divs as well. The said hack sort of ameliorated this on chrome -- not firefox. Is ditching the material goodies the best way to proceed at this point?

The problem is or async component, more specifically the dangerousSetInnerHtml

It's a workaround for a flash of no content

Not sure why it would happen for prerendering though

Hi, any update on this?
The hack is not really working and at the moment which means the production build can't be published.

Is there any way around this? And I mean anything that would allow me to publish this even if that has some downsides?

well you can rename routes to anything else and it won't auto async it

I followed @ForsakenHarmony's advice and renamed the routes directory? Code splitting is disabled but at least it works! 馃帀

I ended up just turning off pre-rendering in my build until this is resolved. Not ideal, but it is better than the dupe.

// In package.json
  "build": "preact build --no-prerender",

@developit has a Suspense based fix for this.
Will wait for his PR

The confusing part is that folks are seeing this in Preact 8. My fix is specific to Preact X.

I'm on Preact X and I think I have the same problem (not sure)

When I develop, after a few changes, my routes are duplicated (all of them). Just force-refreshing the page fix it

preact: 10.3.2
preact-router 3.2.1
preact-cli: 2.2.1

Screenshot 2020-02-28 at 12 05 53

Screenshot 2020-02-28 at 12 05 40

@Pierre-Gilles preact-cli v2 is not really compatible with preact v10

But we still haven't gotten code splitting to work for preact 10 in cli@rc

@ForsakenHarmony Oh I didn't know, thanks !

Any idea of a fix while waiting for preact-cli v3 ?

cli@rc should be usable in it's current form, if you don't need async loading it could work for you

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hardcoar picture hardcoar  路  3Comments

c0debreaker picture c0debreaker  路  4Comments

ajay28kumar picture ajay28kumar  路  3Comments

smjnab picture smjnab  路  3Comments

thangngoc89 picture thangngoc89  路  3Comments