hung-phan / generator-rails-react-webpack

Integrate Ruby on Rails with React.js and Webpack
56 stars 9 forks source link

Server-side Rendering #4

Closed inooid closed 9 years ago

inooid commented 9 years ago

I was wondering whether or not this project uses the benefits of the server-side rendering of React. I used yo rails-react-webpack in an existing project, but on development I couldn't really see the server-side rendering happening.

By the documentation on the page I couldn't really find whether or not it actually makes use of the server-side rendering feature. If it should work on development, then it might be an issue on my side.

hung-phan commented 9 years ago

Hi @inooid, I am aware of the fact React has server side rendering. Good question anyway. I got this from https://github.com/reactjs/react-rails/tree/v1.0.0#server-rendering

To render components on the server, pass prerender: true to react_component:

<%= react_component('HelloMessage', {name: 'John'}, {prerender: true}) %>
<!-- becomes: -->
<div data-react-class="HelloMessage" data-react-props="{&quot;name&quot;:&quot;John&quot;}">
  <h1>Hello, John!</h1>
</div>
(It will be also be mounted by the UJS on page load.)

There are some requirements for this to work:

react-rails must load your code. By convention, it uses components.js, which was created by the install task. This file must include your components and their dependencies (eg, Underscore.js).
Your components must be accessible in the global scope. If you are using .js.jsx.coffee files then the wrapper function needs to be taken into account:

# @ is `window`:
@Component = React.createClass
  render: ->
    `<ExampleComponent videos={this.props.videos} />`
Your code can't reference document. Prerender processes don't have access to document, so jQuery and some other libs won't work in this environment :(

My generator can be configured to have server side rendering for React; however, it can only render simple components right now as it states here Prerender processes don't have access to document, so jQuery and some other libs won't work in this environment. It is actually easy for Webpack to do all the hard works for exporting dependencies to global environment, but if we can't build very rich components, it won't be useful.

My solution for that right now is writing simple components, putting those in app/assets/javascripts/components, and exposing them to global environment, which will allow JS virtual machines to prerender those. Does that answer your question?

inooid commented 9 years ago

Alright, thanks for clearing that up. As far as I know you can make rich components, but not when invoking componentWillMount. Once the server has rendered the initial DOM from the server with the corresponding data (which is componentWillMount), it will then go over to componentDidMount and the client will take care of it. I assume when the componentDidMount is called, you can use your client-side libraries, such as jQuery.

I just haven't found a way to use server-side rendering without using the standard Rails sprockets, but I would love to do so. I feel like using gulp makes my development process so much faster, but if I can't use server-side rendering that way, that would be a huge performance hit, just because of a easier way to develop your app.

If you have found a way to use the server-side rendering with other compilers other than Rails sprockets, hit me up :+1:

hung-phan commented 9 years ago

Just re-read some ideas from another developer - http://bensmithett.github.io/going-isomorphic-with-react/#/40. I think it would be useful to know that we can setup a Node.js server doing server side rendering and let our RoR server consume it.

inooid commented 9 years ago

@hung-phan That's what I thought as well. Just let Rails do it's backend thing and let NodeJS connect to the Rails API (that you build) and render it for you with the data from the Rails app. Then it's the best of both worlds. Rails can do it's backend thing and NodeJS can do it's isomorphic javascript. It just creates a little bit of overhead though.

hung-phan commented 9 years ago

:+1: