Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async component mounted/shown twice at same time #677

Closed
shalomvolchok opened this issue Dec 1, 2018 · 21 comments · Fixed by #1265
Closed

Async component mounted/shown twice at same time #677

shalomvolchok opened this issue Dec 1, 2018 · 21 comments · Fixed by #1265
Assignees
Labels

Comments

@shalomvolchok
Copy link

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’t 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’s still not clear to me what the right solution would be to avoid/fix this. What do you all think?

@prateekbh
Copy link
Member

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

@0xjjpa
Copy link

0xjjpa commented Dec 9, 2018

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

@shalomvolchok
Copy link
Author

A quick temporary hack

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

@0xjjpa
Copy link

0xjjpa commented Dec 11, 2018

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)
};

@prateekbh
Copy link
Member

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

@prateekbh
Copy link
Member

cc: @lukeed

@developit developit added the bug label Jan 3, 2019
@developit
Copy link
Member

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.

@0xjjpa
Copy link

0xjjpa commented Feb 1, 2019

👋 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.

@0xjjpa
Copy link

0xjjpa commented Apr 8, 2019

@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 😢

@pragmatech
Copy link

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?

@ForsakenHarmony
Copy link
Member

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

@lucie-macikova
Copy link

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?

@ForsakenHarmony
Copy link
Member

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

@mfbx9da4
Copy link

mfbx9da4 commented Jun 16, 2019

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

@TheNando
Copy link

TheNando commented Jul 2, 2019

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",

@prateekbh
Copy link
Member

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

@ForsakenHarmony ForsakenHarmony moved this from To do to Needed in Preact-cli 3.0 Jul 12, 2019
@developit
Copy link
Member

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

arnellebalane added a commit to gdg-cebu/devfest19 that referenced this issue Oct 15, 2019
@Pierre-Gilles
Copy link

Pierre-Gilles commented Feb 28, 2020

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

@ForsakenHarmony
Copy link
Member

@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

@Pierre-Gilles
Copy link

@ForsakenHarmony Oh I didn't know, thanks !

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

@ForsakenHarmony
Copy link
Member

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

10 participants