markfinger / python-react

Server-side rendering of React components
MIT License
1.62k stars 116 forks source link

Combining server side rendering with client side #63

Closed selimt closed 8 years ago

selimt commented 8 years ago

Hi, I am trying to follow both the Flask and the Tornado examples to convert a client side React component to render on the server side but still be able to trigger the life cycle methods such as componentDidMount on the client side. So far I haven't been able to figure it out.

componentWillMount fires on the server side but componentDidMount doesn't fire on the client side. I even added the browser check like this to the jsx (based on this article):

if (isNode) {
  exports.TrailApp = TrailApp
} else {
  ReactDOM.render(<TrailApp />, document.getElementById('content'))
}

Is there anything I am missing on the server side?

Thanks -Selim

markfinger commented 8 years ago

It's probably not triggering the mount handler because react's only trying to update it, not re-mount it.

Try componentDidUpdate

selimt commented 8 years ago

I actually managed to get it working. I had to revert back to using non ES6 syntax so that the jsx can be rendered in the browser, then I had to include the jsx in index.html along with all the required packages (react, babel, etc.) then when I loaded it into the browser, it got rendered by the server first and afterwards it got rendered by the browser firing componentDidMount.

The tricky part was to send the props again to the browser render since the ReactDOM.render doesn't know what is passed from the server. I solved it by passing it through the template mechanism to a javascript variable like this:

  <script>
    var APP_PROPS = {{ app_props|tojson }};
  </script>

and using it in the client render like this:

ReactDOM.render(<TrailApp {...window.APP_PROPS} />, document.getElementById('content'))

Thanks -Selim

markfinger commented 8 years ago

Cool :)