在 React Universal 应用程序中 window.__INITIAL_STATE__ 仍然是将初始状态传递给客户端的首选方式吗?

Is window.__INITIAL_STATE__ still the preferred way to pass initial state to the client in React Universal apps?

我目前正在阅读 a book 有关 React 和 Universal 应用程序的文章,其中作者声称以下是将初始状态从服务器传递到客户端的最佳实践:

server.js

import React from 'react';
import {renderToStaticMarkup} from 'react-dom/server';
import Myapp from '../MyApp';
import api from '../services';

function renderPage(html, initialData) {
    return `
        <html>
            <body>
                ${html}
            </body>
            <script>
                window.__INITIAL_STATE__ = ${JSON.stringify(initialData)};
            </script>
            <script src="bundle.js"></script>
        </html>
    `;
}

export default function(request, reply) {
    const initialData = api.getData();
    const html = renderToStaticMarkup(<MyApp />);
    reply(renderPage(html, initialData);
}

然后,在客户端中,您将像这样读出数据:

bundle.js

const initialData = window.__INITIAL_STATE__ || {};
const mountNode = document.getElementById('root');
ReactDOM.render(<MyApp />, mountNode);

据我了解,初始状态首先被转换为字符串,然后作为全局对象文字附加到 window 对象。

这个解决方案在我看来非常粗糙。这本书于 2016 年年中发布。使用 window.__INITIAL_STATE__ 仍然是如何做到这一点的方法还是有更好的解决方案?

例如,我可以想象可以在一个单独的微服务调用中提供初始状态,然后也可以比数据直接嵌入到文档中更好地缓存,因为这样初始状态数据每次页面刷新都必须传输,即使数据没有改变。

HTTP 通过缓存响应来工作,在你的情况下,如果初始状态总是相同的,你也可以在服务器端缓存它并在页面中显示它,它会工作得更快,因为反应将有访问权限立即设置为该值,因此无需等待。您也可以强制浏览器缓存页面,这样页面的响应将与初始状态相同。

对于额外的调用请求,您依靠浏览器来缓存该调用,但您必须构建一个额外的步骤,在信息到达时重新呈现反应或阻止反应以呈现直到信息到达准备好了。

所以我会选择第 1 个,它给你更多的灵活性和其他一些不错的东西,比如服务器渲染,在服务器中加载状态后可以很容易地实现。

简单回答:是的。

但我不确定为什么没有人指出您有一个非常常见的 XSS 漏洞使用 JSON.stringify(initialData) 您想要做的是:

import serialize from 'serialize-javascript';

 window.__INITIAL_STATE__ = ${serialize(initialData)};