React服务器端和客户端渲染不是无缝的

问题描述:

首先页面由服务器渲染,然后在客户端/浏览器端,JavaScript脚本重新渲染整个页面!
我不认为这是应该如何,因为它是非常糟糕的用户体验。React服务器端和客户端渲染不是无缝的

我注意到的一件事是,我的根元素的data-reactid属性由服务器呈现,是一些像.2t5ll4229s这样的散列,并且所有孩子都以前缀为例如。 .2t5ll4229s.0(第一个孩子)。而在浏览器端,data-reactid.0为根元素,.0.0为第一个孩子。
如果data-reactid真的是这里的罪魁祸首,有没有办法为客户端和服务器端设置一个值,如eric123

如果data-reactid不是这里的罪魁祸首,我该如何着手使服务器和客户端渲染React无缝,即只有某些元素应该由客户端重新渲染,而不是所有的东西!?

我的索引服务器local.html模板:

... 
<body> 
    <div id="content" class="container-fluid wrapper no-padding-left no-padding-right"> 
     {{{reactHtml}}} 
    </div> 
    <script src="bundle.js"></script> 
</body> 
... 

我server.js:

server.get('*', function (req, res) { 
     console.log('request url', req.url); 
     log.debug('routes are', JSON.stringify(routes)); 
     res.header("Access-Control-Allow-Origin", "*"); 
     match({routes, location: req.url}, (error, redirectLocation, renderProps) => { 
    if (renderProps) { 
     let htmlStr = React.renderToString(<RoutingContext {...renderProps} />); 
     res.render('index-server-local', { reactHtml: htmlStr });  
    } 
} 

我browser.js:

React.render(<Router history={history} routes={routeConfig} />, document.getElementById('content')); 

我使用react-router 1.0.0和React 0.13.3。

我们需要在服务器端序列化数据(或状态),并将其发送到客户端进行反序列化,否则客户端数据与服务器端渲染时不同。它会重新加载。 一个例外:纯静态页面,在这种情况下的反应我们推荐使用renderToStaticMarkup

类似renderToString,除了这不会产生额外的DOM数据反应的-ID等属性,那阵营内部使用。如果您想将React用作简单的静态页面生成器,这非常有用,因为删除额外的属性可以节省大量的字节。

那么,我们如何序列化 - 反序列化? 下面是一个简单的版本: 在索引服务器local.html模板:

<script src="bundle.js"></script> 

到:

<script dangerouslySetInnerHTML={{{{__html: 'window.__data=' + JSON.stringify({key: 'value'})}}}} /> 
    <script src="bundle.js"></script> 

而在客户端,我们现在可以使用__datadata。如何根据您的选择将数据映射到您的组件。

我建议Reudx此:

createStore(browserHistory, initialState) 

然后

<Provider store={store}> 
    { component } 
    </Provider> 
+0

感谢@大卫关,我得的方式从服务器传递值到浏览器,没有关于后顾之忧。但是,我们如何首先在服务器端获得哈希前缀?我不明白你在说什么,序列化和反序列化如何在这里帮助我 – ericn

+0

@eric'hash prefix'。你在使用hashHistory吗?这对服务器端渲染不起作用。 – Nal