Reactotron: Universal apps (SSR)

Created on 11 Sep 2016  路  7Comments  路  Source: infinitered/reactotron

To debugging server side rendering this would be GREAT and a real benefit to all other dev toolbar solutions.

help wanted

Most helpful comment

SSR is referred to server side rendering of react components, however the whole source code is mostly identical to the browser. SSR uses the same code like the client but instead render it to the DOM it output it as a string inclusively the redux-state (depend on the implementation it makes some more thing like waiting for sagas - mostly api calls). Yes there could be more thing but nothing "relevant".
To be SSR compatible means nothing more than just don't use any browser relevant code.
1) window and window.*, FormData etc. = NO
2) all built-in js std lib objects (or use polyfill) = YES

From lifecycle perspective the main difference is that the server build...

  • wait for incoming request (ex: express.js)

    • creates fresh redux state and populates it like you do in the browser (sagaMiddleware+run, reducer etc.)

    • render the root component to string (to dispatch saga actions which fetch data - this is just one type of a solution to solve the data fetching)

    • wait for all sagas finished (api calls which fetch data for the redux state)

    • render the root component to string (again - now with all the fetched data)

    • set the the rendered component string to the html body

    • place the rendered component string to the body and wrap it with the html basic structure (html headers, and important: the used redux state snapshot as variable)

  • send the html back to the client

How do multiple clients work?: The above procedure can process multiple requests in parallel. Since the whole redux state and it's dependencies (of course redux-saga etc.) are totally fresh instances they never conflict. After the request is processed and the response is sent, the redux-sate is garbage collected since they are only a local vars.

Where is the state held?: Locals vars.

When do you connect to Reactotron?: In the bootstrap of the state initialisation for every request.

How do multiple clients work?: If you run 2 requests to the server it happens the same when you open 2 tabs of the app. Both instances start communicate with the Reactotron server.
Reactotron.clean(); should be used at the beginning of the server request - same like in the browser.

The timeline you can think like: A browser would load the whole application and after all data is loaded the page is closed immediately. With the difference it's a node.js environment.

Examples:
https://github.com/erikras/react-redux-universal-hot-example

Waiting for requests and create new state:
https://github.com/erikras/react-redux-universal-hot-example/blob/master/src/server.js#L63-L72

Just render the root component on the server:
https://github.com/erikras/react-redux-universal-hot-example/blob/master/src/server.js#L63-L72

Wrap the rendered output with the html boilerplate:
https://github.com/erikras/react-redux-universal-hot-example/blob/master/src/server.js#L103-L104

Yeah there are some react-router specific thing but that's not relevant.

All 7 comments

I'd like to, but I've got zero experience with it. Could use some help or a friendly nudge in the right direction. 馃槃

I tried to debug what is not working if start the session in nodejs.
First reactotron-js-react is browser specific (access the window object to fetch the user agent)
So I tried to use reactotron-js-core directly, but I don't get it work, the passed io (socket.io-client) never could connect to the reactotron app.
However the same code worked in the browser.
targeted:
ws://localhost:9090
even tried 127.0.0.1 and the lan IP.
But it always run into timeout after a while.
According to the socket.io docs It should work.

Any idea?

The environment is very similar to react-native since both are nodejs - so I think it will not be a big work after fix some issues.

So I think it make sense to add another package for the server side client at the end?

I'm not sure how SSR works. It makes sense that it should be able to work since it is node. I just dont know how the lifecycle would work. When do you connect to Reactotron? How do multiple clients work? Where is the state held?

It'd be helpful to see a working example. Do you have a repo you could share?

SSR is referred to server side rendering of react components, however the whole source code is mostly identical to the browser. SSR uses the same code like the client but instead render it to the DOM it output it as a string inclusively the redux-state (depend on the implementation it makes some more thing like waiting for sagas - mostly api calls). Yes there could be more thing but nothing "relevant".
To be SSR compatible means nothing more than just don't use any browser relevant code.
1) window and window.*, FormData etc. = NO
2) all built-in js std lib objects (or use polyfill) = YES

From lifecycle perspective the main difference is that the server build...

  • wait for incoming request (ex: express.js)

    • creates fresh redux state and populates it like you do in the browser (sagaMiddleware+run, reducer etc.)

    • render the root component to string (to dispatch saga actions which fetch data - this is just one type of a solution to solve the data fetching)

    • wait for all sagas finished (api calls which fetch data for the redux state)

    • render the root component to string (again - now with all the fetched data)

    • set the the rendered component string to the html body

    • place the rendered component string to the body and wrap it with the html basic structure (html headers, and important: the used redux state snapshot as variable)

  • send the html back to the client

How do multiple clients work?: The above procedure can process multiple requests in parallel. Since the whole redux state and it's dependencies (of course redux-saga etc.) are totally fresh instances they never conflict. After the request is processed and the response is sent, the redux-sate is garbage collected since they are only a local vars.

Where is the state held?: Locals vars.

When do you connect to Reactotron?: In the bootstrap of the state initialisation for every request.

How do multiple clients work?: If you run 2 requests to the server it happens the same when you open 2 tabs of the app. Both instances start communicate with the Reactotron server.
Reactotron.clean(); should be used at the beginning of the server request - same like in the browser.

The timeline you can think like: A browser would load the whole application and after all data is loaded the page is closed immediately. With the difference it's a node.js environment.

Examples:
https://github.com/erikras/react-redux-universal-hot-example

Waiting for requests and create new state:
https://github.com/erikras/react-redux-universal-hot-example/blob/master/src/server.js#L63-L72

Just render the root component on the server:
https://github.com/erikras/react-redux-universal-hot-example/blob/master/src/server.js#L63-L72

Wrap the rendered output with the html boilerplate:
https://github.com/erikras/react-redux-universal-hot-example/blob/master/src/server.js#L103-L104

Yeah there are some react-router specific thing but that's not relevant.

Holy crap man. Thanks for taking the time to write that out.

I use react-boilerplage with SSR branch. got the same problem with @aight8.

Closing. Thanks for great insights in here. 鉂わ笍

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ferminmoli picture ferminmoli  路  4Comments

dhruwal picture dhruwal  路  3Comments

Kida007 picture Kida007  路  4Comments

Eyesonly88 picture Eyesonly88  路  4Comments

tolu360 picture tolu360  路  5Comments