Объект JSON и переменная окна для передачи начального состояния рендеринга на стороне сервера с использованием reactjs

В изоморфном приложении с Reactjs вам необходимо передать идентичное начальное состояние, которое было отображено на сервере, клиенту (который затем «повторно увлажнит» приложение с привязками событий и т. д.).

Я видел два подхода к передаче этого начального состояния вниз:

Установка глобальной переменной в окно:

<script>
window.initialState = {{JSON.stringify(initialState)}} ;
</script>

Или передать его как объект JSON:

<script id="initial-state" type="application/json"> {{JSON.stringify(initialState)}}</script>

Оба легко извлекаются из любого места в приложении. Есть ли преимущества использования одного перед другим?


person Federico    schedule 27.12.2014    source источник
comment
Для меня они оба выглядят очень странно и некрасиво. Я разрабатываю свои компоненты React таким образом, чтобы они хорошо отображались с пустым начальным состоянием и обновляли его, когда сервер отправлял окончательные данные.   -  person daniula    schedule 27.12.2014


Ответы (2)


Последний избегает глобальной переменной, а первый избегает поиска в DOM. Я бы выбрал первый, просто потому, что он требует меньше кода.

Одна проблема заключается в том, что если у вас есть </script в вашем JSON, это может допустить инъекцию или случайную ошибку. Чтобы предотвратить это, вы можете заменить < на \u003c.

<script>
window.initialState = {{
    JSON.stringify(initialState).replace(/</g, '\\u003c')
}}; 
</script>
person Brigand    schedule 27.12.2014

Мне нравится создавать функцию запуска, которая запускает все на сервере и в браузере. На стороне браузера я отображаю этот объект начального состояния в качестве аргумента:

<script type="text/javascript">
    var app = new App();
    document.addEventListener('DOMContentLoaded', function(e) {
        document.removeEventListener('DOMContentLoaded');

        app.start({{JSON.stringify(initialState)}});
    });
</script>

В функции запуска у меня есть что-то вроде этого для браузера:

App.prototype.start = function(initState) {
    React.render(RootComponent(initState), document.getElementById('container'));
}

В этом случае start() мало что делает, но в полной реализации я бы также обрабатывал здесь рендеринг на стороне сервера. Большинство моих идей для этого пришло из этого выступления и примеров: https://github.com/zertosh/ssr-demo-kit

person Shawn    schedule 28.12.2014