Является ли window.__INITIAL_STATE__ предпочтительным способом передачи начального состояния клиенту в приложениях React Universal?

В настоящее время я читаю книгу о приложениях 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);

Из того, что я понимаю, это то, что начальное состояние сначала преобразуется в строку, а затем присоединяется как глобальный объектный литерал к объекту окна.

Это решение выглядит очень грубым для меня. Книга была выпущена в середине 2016 года. Является ли использование window.__INITIAL_STATE__ еще способ как это сделать или есть лучшие решения?

Например, я мог бы предположить, что было бы возможно предложить начальное состояние в отдельном вызове микросервиса, который затем также мог бы кэшироваться лучше, чем если бы данные были встроены непосредственно в документ, потому что тогда данные начального состояния должны передаваться каждый раз. время обновления страницы, даже если данные не изменились.

2 ответа

Простой ответ: да.

Но я не уверен, почему никто не указал, что у вас есть очень распространенная уязвимость XSS, использующая JSON.stringify(initialData) вместо этого вы хотите:

import serialize from 'serialize-javascript';

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

HTTP работает путем кэширования ответов, в вашем случае, если начальное состояние всегда будет одинаковым, вы также можете кэшировать это на стороне сервера и отображать его на странице, оно будет работать быстрее, потому что реагирование будет иметь доступ сразу к этому значению, поэтому ждать не придется. Также вы можете также принудительно заставить браузер кэшировать страницу, поэтому отклик на странице будет таким же, а исходное состояние не изменится.

С дополнительным запросом вызова вы полагаетесь на браузер для кеширования этого вызова, но вам придется создать дополнительный шаг, сделать повторную визуализацию реагирования при поступлении информации или заблокировать реакцию на визуализацию, пока информация не будет готова.

Итак, я пойду с номером 1, он даст вам больше гибкости и еще чего-то приятного, например, рендеринг сервера, который может быть легко достигнут после загрузки состояния на сервер.

Другие вопросы по тегам