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

Portal is overriding the lazy loaded sibling after hydration under specific conditions #1413

Closed
kevintakeda opened this issue Dec 10, 2022 · 1 comment
Labels
bug Something isn't working
Milestone

Comments

@kevintakeda
Copy link

kevintakeda commented Dec 10, 2022

Describe the bug

If I use a component like below inside a For, after hydration it renders the Portal but not the lazy component. That bug is hard to reproduce because it happens only when: using a fragment element, a portal and a lazy component inside a For component. See the reproduction to see it happen.

<>
  <Lazy />
  <Portal>Portal</Portal>
</>

The workaround is to use a div instead a fragment, or wrap either the portal or the lazy component in a div.

Your Example Website or App

https://stackblitz.com/edit/vitejs-vite-fsxu78?file=src%2FApp.tsx,src%2FLazy.tsx,src%2FComponent.tsx

Steps to Reproduce the Bug or Issue

  1. Create a lazy component
  2. Create a component that returns a Fragment containing a Portal element and a lazy component
  3. Render the component (from step 2) inside a For
  4. Render the SSR and hydrate it

Expected behavior

After hydration the component renders the portal and it's sibling element.

Screenshots or Videos

No response

Platform

  • Browser: Chrome
  • Version: solid-js 1.6.4

Additional context

No response

@ryansolid ryansolid added the bug Something isn't working label Dec 13, 2022
@ryansolid
Copy link
Member

ryansolid commented Dec 13, 2022

Thanks for reporting. This is an issue with how Portal works. It doesn't really hydrate properly. Which I figured was fine since it doesn't really work during SSR. Like you can't portal into nothing. There is a mechanism to make it delay client render immediately after hydration but it doesn't take into account the havoc the marker (we use to lookup the parent for event delegation) causes on hydration. I need a new approach.

EDIT: Having tried a number of things fixing this isn't trivial. While the existing bug is on Portal, any fix exposes a more awkward issue. A lazy component in fragments where siblings can flicker faster than the lazy code loads in can cause the server-rendered content to disappear until the lazy code comes back in. It's because ultimately the DOM reconciliation will handle them together and the code isn't there. It is very edge sort of issue that is mostly a timing issue. But this requires larger change to get it working.

Best workaround right now is probably wrapping the Portal in a <div>.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants