You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React SSR项目使用@loadable/component出现hydration警告求助

Fixing "Did not expect server HTML to contain a
in
" Warning with @loadable/component in SSR

This warning (and the annoying page flicker) is definitely tied to how @loadable/component handles server-side rendering (SSR) out of the box. When you use dynamic code splitting without proper SSR configuration, there’s a mismatch between what the server renders and what the client tries to hydrate initially. Let’s break down why this happens and how to fix it:

Why the Issue Happens

When you use loadable() for dynamic imports:

  • On the server, if you don’t explicitly preload the dynamic component, @loadable/component won’t render the actual component content during SSR—it’ll render an empty placeholder (or nothing at all) instead.
  • On the client, before the dynamic chunk finishes loading, the loadable component also renders a placeholder. Once the chunk loads, it replaces the placeholder with the real component, causing that flicker.
  • Even if you think server and client output match, the initial hydration state on the client doesn’t align with what the server sent, triggering React’s strict mismatch warning.

When you switch to direct imports, the component loads synchronously on both server and client, so the rendered HTML matches perfectly from the start—no mismatch, no flicker.

Step-by-Step Fixes

1. Add SSR Support for @loadable/component

First, install the server-side package that handles capturing and preloading dynamic components:

npm install @loadable/server

2. Update Your Server Rendering Code

Modify your server to capture, preload, and sync dynamic components before rendering:

import { LoadableCapture } from '@loadable/server'
import { renderToString } from 'react-dom/server'
import App from './App'
// This file is generated by @loadable/webpack-plugin (see next step)
import loadableStats from '../dist/loadable-stats.json'

async function renderServerSide(req, res) {
  // Capture all dynamic components used in the app
  const capture = new LoadableCapture()
  
  // Wrap your app with the capture utility
  const serverHtml = renderToString(
    <LoadableCapture capture={capture}>
      <App />
    </LoadableCapture>
  )

  // Preload all captured dynamic components
  await capture.preloadAll(loadableStats)

  // Get the loadable state to pass to the client
  const loadableState = JSON.stringify(capture.getState())

  // Inject the state into your HTML template
  res.send(`
    <!DOCTYPE html>
    <html>
      <body>
        <div id="root">${serverHtml}</div>
        <!-- Pass loadable state to client to sync hydration -->
        <script>window.__LOADABLE_STATE__ = ${loadableState}</script>
        <script src="/path/to/your/client/bundle.js"></script>
      </body>
    </html>
  `)
}

3. Configure Webpack to Generate Loadable Stats

Install the webpack plugin that creates the loadable-stats.json file needed for preloading:

npm install @loadable/webpack-plugin --save-dev

Add it to your webpack config:

const LoadablePlugin = require('@loadable/webpack-plugin')

module.exports = {
  // ... your existing webpack config
  plugins: [
    // ... other plugins
    new LoadablePlugin(),
  ],
}

4. Adjust Client-Side Hydration

Modify your client entry file to wait for loadable components to be ready before hydrating:

import { loadableReady } from '@loadable/component'
import { hydrate } from 'react-dom'
import App from './App'

// Wait for all dynamic components to load before hydrating
loadableReady(() => {
  hydrate(<App />, document.getElementById('root'))
})

Verify the Fix

After implementing these changes:

  • The server will preload all dynamic components during SSR, so it renders the actual component content instead of a placeholder.
  • The client receives the loadable state, so it knows which components are already loaded and avoids rendering a placeholder during hydration.
  • This eliminates the DOM mismatch warning and the page flicker caused by dynamic chunk loading.

内容的提问来源于stack exchange,提问作者Alejandro Garcia Anglada

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:21:20