Skip to content

Hydration flash using loadable-components - Did not expect server HTML to contain a <div> in <div> #135

Closed
@kirkchris

Description

Our app is still experiencing white page flashes when rehydrating from the snapshotted HTML. Originally we believe it was due to not using loadable-components since we had code splitting, but after implementing loadable-components, still seeing the issue.

Here is where we load the app:

import React from 'react';
import { hydrate, render } from 'react-dom';
import { Router, Route, Redirect, applyRouterMiddleware, IndexRoute } from 'react-router';
import { getState, loadComponents } from 'loadable-components';

const rootElement = document.getElementById('main-view');
let renderMethod = render;
if (rootElement.hasChildNodes()) {
  renderMethod = (app, doc) => {
    loadComponents().then(() => hydrate(app, doc))
  };
}

renderMethod(
  <ErrorBoundary>
    <Router history={ParabolaBrowserHistory} render={applyRouterMiddleware(useScroll())}>
      <Route
        path="/"
        component={LoadableComponents.MainContainer}
        onEnter={verify}
      >
     ...
    </Router>
  </ErrorBoundary>,
  rootElement,
);

// react snap state
window.snapSaveState = () => getState();

The LoadableComponents.* are defined like this:

export const MainContainer = loadable(() =>
  import(/* webpackChunkName: "MainContainer" */ './components/MainContainer'),
);

Now I've been able to verify that the state is populating correctly into window from loadable-components and it does call the code and say components are loaded prior to running hydrate. When running on dev react throws this warning - and when breakpointing in it appears to throw it on the rootElement, not a nested element:

Did not expect server HTML to contain a <div> in <div>.

I've checked my snapshotted HTML and my fully rendered (via JS) html after the white flash and the contents inside of rootElement match exactly. My concern there was something was causing a mismatch leading react not to hydrate appropriately.

My guess is that even though the components are done loading via loadable-components, for some reason react is still being rendered once with no content, which is causing the mismatch.

Any ideas for what might cause this? We're using react-router v3.2.0 and react 16.2.0.

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions