【问题标题】:React server-side and client side rendering not seamless反应服务器端和客户端渲染不是无缝的
【发布时间】:2016-08-19 17:45:02
【问题描述】:

首先页面由服务器渲染,然后在客户端/浏览器端,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-router 1.0.0 和 React 0.13.3。

【问题讨论】:

    标签: express reactjs react-router


    【解决方案1】:

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

    类似于 renderToString,除了它不会创建 React 内部使用的额外 DOM 属性,例如 data-react-id。如果您想将 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。如何根据您的选择将数据映射到您的组件。

    为此我推荐Reudx

       createStore(browserHistory, initialState)
    

    然后

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

    【讨论】:

    • 谢谢@David Guan,我有办法将值从服务器传递到浏览器,不用担心。但是,我们首先如何在服务器端获取哈希前缀?我不明白你在说什么,序列化和反序列化如何在这里帮助我
    • @eric '哈希前缀'。你在使用 hashHistory 吗?这不适用于服务器端渲染。
    猜你喜欢
    • 2017-12-29
    • 2015-05-09
    • 2017-12-08
    • 1970-01-01
    • 2015-09-06
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多