反应服务器端渲染和webpack的延迟加载

时间:2017-02-23 19:34:10

标签: reactjs webpack redux lazy-loading server-side

我正在使用服务器端渲染,使用import()方法延迟加载Webpack 2.2.0,并且只使用babel-plugin-transform-ensure-ignore作为服务器端,所有内容都运行没有错误,并且除了一件事之外完全正常工作。 当页面加载时我可以看到服务器端渲染,但是当webpack调用我的动态组件时,所有页面再次呈现,这对用户是可见的。 我需要知道如何处理这些问题。 我发现它时,我的第一行是

<div data-reactroot="" data-reactid="1" data-react-checksum="-1269702275">

但是当我的延迟加载的组件被解析并执行时,我的react根元素的整个内容被删除并再次渲染,我的第一个元素是<div data-reactroot>

希望有人可以帮助我。

提前致谢!

注意

关于校验和没有反应警告。

更新2/4/2017

这是我的app标记

<div id="app">
    <div>
        <%- body %>
    </div>
</div>

id为app的div是我的反应应用容器

更新3/4/2017

将我的标记更改为

之后

<div id="app"><%- body %></div>

终于对客户端发现的校验和作出反应,但我收到了这个错误。

  

React试图在容器中重用标记,但校验和是   无效。这通常意味着您正在使用服务器渲染和   在服务器上生成的标记不是客户端的标记   期待。反应注入新的标记,以补偿哪些有效,但你   失去了服务器渲染的许多好处。相反,图   了解为什么生成的标记在客户端或服务器上是不同的:

     

(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>

我认为应该生成相同的代码!

2 个答案:

答案 0 :(得分:1)

您报告的行为听起来不正常。

您是否正在使用任何webpack插件从控制台中删除警告?

为了找出发生了什么,我将从调试canReuseMarkup内的ReactMount.js函数开始,查找客户端生成的校验和是否与生成的校验和类似。服务器

重新出现后没有校验和的原因 正如Charlie Marsh在here中提到的那样:

  

如果检查在服务器上呈现的React组件(即使用renderComponentToString生成),您会注意到它有一个不熟悉的属性,数据反应校验和,您在客户端组件上看不到的。   进一步深入addChecksumToMarkup函数会发现数据反应校验和是从HTML标记生成的Adler-32校验和,并附加到服务器端呈现的任何组件。

答案 1 :(得分:1)

调试后,我发现了与React Router连接的问题。 因此,Router元素会在<!-- react empty -->使用延迟加载的情况下呈现import,这就是为什么我的服务器端校验和不匹配的原因。

所以关注this示例我解决了问题,重新渲染。 现在我的代码看起来像这样。

match({ history, routes }, (error, redirectLocation, renderProps) => {
    ReactDOM.render(
           <Provider store={store}>
                <Router {...renderProps} />
           </Provider>, document.getElementById('app')
    )
})