Skip to content

mhart/react-server-example

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

103 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

react-server-example

A simple (no compile) example of how to do server-side rendering with the React library so that component code can be shared between server and browser, as well as getting fast initial page loads and search-engine-friendly pages.

A more complex example with shared routing and data fetching can be found at react-server-routing-example.

Example

$ npm install
$ node server.js

Then navigate to http://localhost:3000 and click on the button to see some reactive events in action.

Try viewing the page source to ensure the HTML being sent from the server is already rendered (with checksums to determine whether client-side rendering is necessary)

Here are the files involved:

App.js:

var createReactClass = require('create-react-class')
var DOM = require('react-dom-factories')
var div = DOM.div, button = DOM.button, ul = DOM.ul, li = DOM.li

// This is just a simple example of a component that can be rendered on both
// the server and browser

module.exports = createReactClass({

  // We initialise its state by using the `props` that were passed in when it
  // was first rendered. We also want the button to be disabled until the
  // component has fully mounted on the DOM
  getInitialState: function() {
    return {items: this.props.items, disabled: true}
  },

  // Once the component has been mounted, we can enable the button
  componentDidMount: function() {
    this.setState({disabled: false})
  },

  // Then we just update the state whenever its clicked by adding a new item to
  // the list - but you could imagine this being updated with the results of
  // AJAX calls, etc
  handleClick: function() {
    this.setState({
      items: this.state.items.concat('Item ' + this.state.items.length),
    })
  },

  // For ease of illustration, we just use the React JS methods directly
  // (no JSX compilation needed)
  // Note that we allow the button to be disabled initially, and then enable it
  // when everything has loaded
  render: function() {

    return div(null,

      button({onClick: this.handleClick, disabled: this.state.disabled}, 'Add Item'),

      ul({children: this.state.items.map(function(item) {
        return li(null, item)
      })})

    )
  },
})

browser.js:

var React = require('react')
var ReactDOM = require('react-dom')
// This is our React component, shared by server and browser thanks to browserify
var App = React.createFactory(require('./App'))

// This script will run in the browser and will render our component using the
// value from APP_PROPS that we generate inline in the page's html on the server.
// If these props match what is used in the server render, React will see that
// it doesn't need to generate any DOM and the page will load faster

ReactDOM.render(App(window.APP_PROPS), document.getElementById('content'))

server.js: