JSON object vs window variable for passing server-side rendered initial state using reactjs
Asked Answered
M

2

3

In an isomorphic application with Reactjs, you need to pass the identical initial state that was rendered on the server down to the client (which will then 'rehydrate' the app with event bindings and such).

I've seen two approaches to passing this initial state down--

Setting a global variable to the window:

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

Or passing it as a JSON object:

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

Both are easily retrievable from anywhere in the application. Are there any advantages to using one over the other?

Miguel answered 27/12, 2014 at 17:25 Comment(1)
For me both of them looks very weird and ugly. I design my React components in a way that they will render nicely with empty initial state and updates it when server sends back final data.Lifetime
V
6

The latter avoids a global variable and the former avoids a DOM lookup. I'd go with the former, just because it requires less code.

One concern is if you have </script in your JSON it could allow injection or accidental error. To prevent this you can replace < with \u003c.

<script>
window.initialState = {{
    JSON.stringify(initialState).replace(/</g, '\\u003c')
}}; 
</script>
Vivia answered 27/12, 2014 at 18:33 Comment(0)
U
1

I like to create a start function that kicks things off on the server and in the browser. On the browser side I render that initial state object as an argument:

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

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

In the start function, I have something like this for the browser:

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

In this case start() doesn't do much, but in a full implementation I would also handle the server-side rendering here. Most of my ideas for this came from this talk and examples: https://github.com/zertosh/ssr-demo-kit

Unsphere answered 28/12, 2014 at 15:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.