2

我正在构建一个反应应用程序,我在客户端上为bundle. 我的应用程序在我使用时在服务器上正确呈现SSR,我在服务器上没有代码拆分,但在客户端我有。我在客户端上收到以下警告hydrate

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

@loadable/component用于客户端上的代码拆分

我在客户端有我的 App.js 文件:-

import React from "react" 
import loadable from '@loadable/component'
import { Route, Switch } from 'react-router-dom'

const AsyncHome = loadable(() =>
  import('./components/Home/Home')  
)
const AsyncPost = loadable(() =>
  import('./components/Post/Post')
)

function App(){
   return(
       <div>
         <Switch>
             <Route path="/" component={AsyncHome}/>
             <Route path="post" component={AsyncPost}/>
           </Switch>
       </div>
    )
}

我在客户端上有我的index.js文件:

import React from 'react'
import { hydrate } from 'react-dom'
import { BrowserRouter} from 'react-router-dom'
import App from './App'

hydrate(
    <BrowserRouter><App/></BrowserRouter>,
    document.getElementById('app')
)

如何通过code-splitting仅在客户端上使用来修复该警告。我也尝试过React.lazyReact.Suspense但我遇到了同样的错误。

4

1 回答 1

0

您需要确保您尝试在客户端进行水合的容器与在服务器端呈现的容器相同。请查看反应文档

话虽如此,代码拆分是为了实现更小的 JS 包,这意味着我们提前计划好如何根据用例拆分代码。我们不在客户端执行该运行时。不过,我可能会遗漏一些东西,所以如果你能分享尝试这样做的原因,那将会有所帮助。但是,在服务器端,您可以选择执行以下操作:

const AsyncHome = loadable(() =>
  import(
    /* webpackChunkName: "home" */
    /* webpackPrefetch: true */
    './components/Home'
  ),
);
const AsyncPost = loadable(() =>
  import(
    /* webpackChunkName: "post" */
    /* webpackPrefetch: true */
    './components/Post'
  ),
);

如果您不想在应用程序中显式跟踪您的代码拆分块,另一种更好的方法是使用ChunkExtractor插件来实现相同的目标此外,为了避免在服务器端呈现,您需要确保组件在安装时初始化@loadable/server只会发生在客户端

let HomeComponent = () => <div/>
let PostComponent = () => <div/>

function App(){
   useEffect(() => {
    HomeComponent = loadable(() =>
      import(
        /* webpackChunkName: "home" */
        /* webpackPrefetch: true */
        './components/Home'
      ),
    );
    PostComponent = loadable(() =>
      import(
        /* webpackChunkName: "post" */
        /* webpackPrefetch: true */
        './components/Post'
      ),
    );
  }, []);
}
于 2020-07-19T13:50:06.473 回答