React服务端渲染和客户端渲染无法无缝衔接。

7

首先页面由服务器渲染,然后在客户端/浏览器端,Javascript脚本重新渲染整个页面!我认为这不是预期的结果,因为它对用户体验非常不友好。

我注意到一个问题,即由服务器呈现的根元素的data-reactid属性是一些哈希值,例如.2t5ll4229s,而所有子元素都有该哈希值作为前缀,例如第一个子元素为.2t5ll4229s.0。然而,在浏览器端,data-reactid为根元素是.0,第一个子元素是.0.0
如果data-reactid真的是问题所在,是否有方法可以将其设置为选择的值,例如同时适用于客户端和服务器端的eric123

如果data-reactid不是问题所在,我该如何使React的服务器端和客户端渲染无缝,即只有某些元素应由客户端重新渲染,而不是全部重新渲染?

我的index-server-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 0.13.3和react-router 1.0.0。

1个回答

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

类似于renderToString,但是它不会创建额外的DOM属性,例如data-react-id,这是React在内部使用的。如果您想将React用作简单的静态页面生成器,则去除额外的属性可以节省大量字节。

那么,我们如何进行序列化和反序列化呢? 以下是一个简单的版本: 在您的index-server-local.html模板中:

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

至:

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

在客户端,我们现在可以使用 __datadata。如何将数据映射到您的组件取决于您的选择。
我建议使用 Redux:
   createStore(browserHistory, initialState)

然后

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

谢谢@David Guan,我已经有办法从服务器传递值到浏览器了,不用担心。但是,我们如何在服务器端首先获取哈希前缀呢?我不明白你在说什么,序列化和反序列化怎么能帮助我呢? - ericn
@eric '哈希前缀'。你正在使用hashHistory吗?这在服务器端渲染中是行不通的。 - Nal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接