React服务端渲染和webpack的懒加载
React server side rendering and lazy loading of webpack
我正在使用服务器端渲染,使用 import()
方法延迟加载 Webpack 2.2.0,并且仅将 babel-plugin-transform-ensure-ignore
用于服务器端,一切都运行无误并且除了一件事外工作完美。
加载页面时,我可以看到服务器端渲染,但是当 webpack 调用我的动态组件时,所有页面都会再次渲染,这对用户是可见的。
我需要知道如何处理此类问题。
我看到它时找到了它,我的第一行是
<div data-reactroot="" data-reactid="1" data-react-checksum="-1269702275">
但是当我的延迟加载组件被解析和执行时,我的反应根元素的全部内容被删除并再次呈现,我的第一个元素是 <div data-reactroot>
希望有人能帮助我。
提前致谢!
注意
没有关于校验和的反应警告。
2017 年 2 月 4 日更新
这是我的应用标记
<div id="app">
<div>
<%- body %>
</div>
</div>
div with id app
是我的反应应用程序容器
2017 年 3 月 4 日更新
在我将标记更改为
之后
<div id="app"><%- body %></div>
终于对客户端找到的校验和做出反应,但我收到了这个错误。
React attempted to reuse markup in a container but the checksum was
invalid. This generally means that you are using server rendering and
the markup generated on the server was not what the client was
expecting. React injected new markup to compensate which works but you
have lost many of the benefits of server rendering. Instead, figure
out why the markup being generated is different on the client or server:
(client) <!-- react-empty: 1 -
(server) <div data-reactroot="
我的客户端根元素是
<Provider store={store}>
<Router history={history} routes={routes} onUpdate={() => window.scrollTo(0, 0)}/>
</Provider>
并且服务器是
<Provider store={store}>
<RouterContext {...renderProps} />
</Provider>
我认为应该生成相同的代码!
您报告的行为听起来很不正常。
您是否使用任何 webpack 插件从您的控制台中删除警告?
为了查明发生了什么,我将从调试 React 的 ReactMount.js
中的 canReuseMarkup
函数开始,看看客户端生成的校验和是否与服务器上生成的校验和相似。
重新渲染后没有显示校验和的原因
正如查理·马什在 here 中提到的那样:
If you inspect a React component that's been rendered on the server (i.e., generated with renderComponentToString
), you'll notice that it has an unfamiliar attribute, data-react-checksum, which you won't have seen on client-side components.
Stepping one level deeper into the addChecksumToMarkup
function reveals that data-react-checksum is an Adler-32 checksum generated from the HTML markup and appended to any component rendered server-side.
调试后我发现了与 React Router 相关的问题。
所以 Router
元素呈现 <!-- react empty -->
如果应用程序使用延迟加载 import
,这就是我的服务器端校验和不匹配的原因。
因此,按照 this 示例,我通过重新渲染解决了问题。
现在我的代码看起来像这样。
match({ history, routes }, (error, redirectLocation, renderProps) => {
ReactDOM.render(
<Provider store={store}>
<Router {...renderProps} />
</Provider>, document.getElementById('app')
)
})
我正在使用服务器端渲染,使用 import()
方法延迟加载 Webpack 2.2.0,并且仅将 babel-plugin-transform-ensure-ignore
用于服务器端,一切都运行无误并且除了一件事外工作完美。
加载页面时,我可以看到服务器端渲染,但是当 webpack 调用我的动态组件时,所有页面都会再次渲染,这对用户是可见的。
我需要知道如何处理此类问题。
我看到它时找到了它,我的第一行是
<div data-reactroot="" data-reactid="1" data-react-checksum="-1269702275">
但是当我的延迟加载组件被解析和执行时,我的反应根元素的全部内容被删除并再次呈现,我的第一个元素是 <div data-reactroot>
希望有人能帮助我。
提前致谢!
注意
没有关于校验和的反应警告。
2017 年 2 月 4 日更新
这是我的应用标记
<div id="app">
<div>
<%- body %>
</div>
</div>
div with id app
是我的反应应用程序容器
2017 年 3 月 4 日更新
在我将标记更改为
之后<div id="app"><%- body %></div>
终于对客户端找到的校验和做出反应,但我收到了这个错误。
React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
(client) <!-- react-empty: 1 -
(server) <div data-reactroot="
我的客户端根元素是
<Provider store={store}>
<Router history={history} routes={routes} onUpdate={() => window.scrollTo(0, 0)}/>
</Provider>
并且服务器是
<Provider store={store}>
<RouterContext {...renderProps} />
</Provider>
我认为应该生成相同的代码!
您报告的行为听起来很不正常。
您是否使用任何 webpack 插件从您的控制台中删除警告?
为了查明发生了什么,我将从调试 React 的 ReactMount.js
中的 canReuseMarkup
函数开始,看看客户端生成的校验和是否与服务器上生成的校验和相似。
重新渲染后没有显示校验和的原因 正如查理·马什在 here 中提到的那样:
If you inspect a React component that's been rendered on the server (i.e., generated with
renderComponentToString
), you'll notice that it has an unfamiliar attribute, data-react-checksum, which you won't have seen on client-side components. Stepping one level deeper into theaddChecksumToMarkup
function reveals that data-react-checksum is an Adler-32 checksum generated from the HTML markup and appended to any component rendered server-side.
调试后我发现了与 React Router 相关的问题。
所以 Router
元素呈现 <!-- react empty -->
如果应用程序使用延迟加载 import
,这就是我的服务器端校验和不匹配的原因。
因此,按照 this 示例,我通过重新渲染解决了问题。 现在我的代码看起来像这样。
match({ history, routes }, (error, redirectLocation, renderProps) => {
ReactDOM.render(
<Provider store={store}>
<Router {...renderProps} />
</Provider>, document.getElementById('app')
)
})