preactjs / preact

βš›οΈ Fast 3kB React alternative with the same modern API. Components & Virtual DOM.
https://preactjs.com
MIT License
36.69k stars 1.95k forks source link

Hydrate results in two HTML DOMs #2418

Closed kanishk-anand-oyo closed 4 years ago

kanishk-anand-oyo commented 4 years ago

I am migrating a project from Preact 8 to Preact X, and have been successful in the migration, and after reading the documentation, I want to leverage the hydrate property, to make the preact-app more performant. But as soon as I use hydrate, inplace of render, it results in displaying the App twice, one from SSR, and one after CSR.

On SSR I am using

renderStylesToString(
   renderToString(
       <IntlProvider locale={appLocale.locale} messages={messages}>
            <CookiesProvider cookies={new Cookies(req.headers.cookie)}>
               <Provider store={store} key="provider">
                  <RouterContext {...renderProps} />
                 </Provider>
              </CookiesProvider>
         </IntlProvider>
       )
 );

and on CSR, the App is initialised using :

hydrate(
    <IntlProvider locale={locale} messages={appMessages}>
      <CookiesProvider>
        <Provider store={store}>
          <Router />
        </Provider>
      </CookiesProvider>
    </IntlProvider>,
    document.getElementById('root')
  );

I am using renderStylesToString due to usage of Emotion. Even after removing renderStylesToString , the HTML DOM appears twice.

Expected Behavior

It should render one App, while registering event handlers, and re-rendering only those components whose attributes/DOM differs.

Actual Behavior

The HTML DOM appears once, while attaching event handlers.

JoviDeCroock commented 4 years ago

Hey,

Could you provide a reproduction for this since it sounds like the actual dom being transmitted differs a lot from the one hydrated (only explanation I can come to at this point).

That being said,

and re-rendering only those components whose attributes/DOM differs.

Props aren’t diffed during hydration, this is expected

kanishk-anand-oyo commented 4 years ago

Attaching screenshots for the reference, will provide a live URL in a while.

SSR output : <--- Removed Screenshots -->

CSR output:

<--- Removed Screenshots -->

Combined:

<--- Removed Screenshots -->

JoviDeCroock commented 4 years ago

It would be easier for us if you could provide a reproduction, I don't mean to make this hard on you but it's very hard to derive what is being done from screenshots or hypothetical code examples where we don't know what the implementation of those components used are (in this case Providers).

kanishk-anand-oyo commented 4 years ago

Sure, let me see how can I reproduce the same on sandbox.

JoviDeCroock commented 4 years ago

Here's a start: https://codesandbox.io/s/keen-breeze-39fdh

kanishk-anand-oyo commented 4 years ago

I created sample project with data flow similar to the main project, and for the sample project the hydrate function works fine. I guess I need to inspect what is causing the DOM to change drastically on client side. Thanks for the support!

developit commented 4 years ago

Might be okay to close this issue since it's likely something to do with the specific SSR/CSR handling?

kanishk-anand-oyo commented 4 years ago

Done. Seems like issue with application itself.