title: Facebook React.js: how do you render stateful components on the server?
body: <p>I think I'm conceptually missing something with server-side rendering using React.js</p>
  
  <p>Assume I want to create a page to display items from a server-side DB, with an input field 
  to filter them. </p>
  
  <p>I want a page:</p>
  
  <ul>
  <li>that responds to a URL like <code>/items?name=foobar</code></li>
  <li>with a React input field to filter the items by name</li>
  <li>with a React component to display the list of filtered items</li>
  </ul>
  
  <p>Assume I have a public REST API to query the items on the client side.</p>
  
  <p>Conceptually, what I want to do at first request (<code>GET /items?name=foobar</code>) is : </p>
  
  <ul>
  <li>I want my input field to show what the user passed as a Parameter, so I need to 
  pass the query parameter ('foobar') to the react component, as a 'prop' (like <code>initialName</code>)</li>
  </ul>
  
  <p>So I tried this: </p>
  
  <pre><code> // A stateful component, maintaining the value of a query field
   var ItemForm = React.createClass({
      getInitialState : function () {
          return {
              name : this.props.initialName
          };
      },
      handleInputValueChanged : function() {
          var enteredName = this.refs.query.getDOMNode().value.trim();
          this.props.onNameChanged(enteredName);
      },
      render : function () {
  
          return React.DOM.form({
              children : [
                  React.DOM.label({
                      children : "System name"
                  }),
                  React.DOM.input({
                      ref : "query",
                      value : this.state.name,
                      onChange : this.handleInputValueChanged
                  })
              ]
          });
      }
  });
  </code></pre>
  
  <ul>
  <li>I also have to do my database query <em>on the server</em> to get a list of items, and
  pass this list of items as a 'prop' of the ItemList (like 'initialItems')</li>
  </ul>
  
  <p>As I understand it, I need a simple component to display the list, receiving it as a 'prop': </p>
  
  <pre><code> // A stateless component, displaying a list of item
   var ItemList = return React.createClass({
  
      propTypes : {
          items : React.PropTypes.array
      },
  
      render : function () {
          return React.DOM.ul({
              children : _.map(this.props.items, function (item) {
                  return React.DOM.li({
                      children : [
                          React.DOM.span({
                              children : ["Name : ", item.name].join(" ")
                          })]
                  });
              })
          });
      }
  });
  </code></pre>
  
  <ul>
  <li>Now, I need a component do display the whole Page ; this component will have to maintain the state of the whole page, that is, look at the name entered in the field, and make API queries to update the list items. 
  However I don't understand how this component can have an 'initialState' that would work both on the server-side and for later rendering on the client side. </li>
  </ul>
  
  <p>I tried this: </p>
  
  <pre><code> // A stateful react component, maintaining the list of items
   var ItemPage = React.createClass({
  
      getInitialState : function () {
          // ?????
          // This is where I'm sure the problem lies. 
          // How can this be known both on server and client side ? 
          return {
              items : this.props.initialItems || []
          };
      },
      queryItems : function (enteredName) {
  
          var self = this;
  
          // The field was emptied, we must clear everything
          if (!enteredName) {
              this.setState({
                  items : []
              });
  
          } else {
  
              // The field was changed, we want to do a query
              // then change the state to trigger a UI update. 
              // The query code is irrelevant, I think.
              doQuery(enteredName).then(function (items) {
                  self.setState({
                     items : items
                  });
              });
          }
      },
      render : function () {
  
          // I don't want to display the same view
          // if there is no results. 
          // This uses a 'state' property of the page
          var results = null;
          if (_.isEmpty(this.state.items)) {
              results = React.DOM.div({
                  ref : "results",
                  children : "No results"
              });
          } else {
              results = ItemListView({
                  // Here items is a 'prop', the ItemList is technically
                  // stateless
                  items : this.state.items
              });
          }
  
          return React.DOM.div({
              children : [
                  ItemForm({
                      initialName : this.props.initialName,
                      onNameChanged : this.queryItems
                  }),
                  results
              ]
          });
      }
  });
  </code></pre>
  
  <p>That's where I'm stuck. I can render things on the server side using something like:</p>
  
  <pre><code>var name = // The name from the query parameters
  var items = doQueryOnServerSide(name);
  React.renderComponentAsString(ItemPage({
    initialName : name,
    initialItems : items
  });
  </code></pre>
  
  <p>But when I try to do write the client side javascript, what should I do ? I know where I want my dom to be rendered, but what initial props should I pass to the react component? </p>
  
  <pre><code>React.renderComponent(ItemPage({
    initialName : ??? // Read the name parameter from URL ? 
    initialItems : ??? // I don't know yet, and I don't want to make an API call until the user entered something in the input box 
  });
  </code></pre>
  
  <p>Most attempts I have tried ends up with the DOM being 'erased' on the client-side, with this message:</p>
  
  <blockquote>
    <p>React attempted to use reuse markup in a container but the checksum
    was invalid. This generally means that you are using server rendering
    and the markup generated on the server was not what the client was
    expecting. React injected new markup to compensate which works but you
    have lost many of the benefits of server rendering. Instead, figure
    out why the markup being generated is different on the client or
    server.</p>
  </blockquote>
  
  <p>Note that only the markup of my ItemList component is erased, so I suppose it's an implementation problem of my component, but I don't really know where to start.</p>
  
  <p>Am I on the right track? Or do I miss something entirely? </p>