title: Efficiently structuring large React.js applications with multiple views
body: <p>I have a react application with multiple views (e.g. <code>Profile</code>, <code>Followers</code>).  Each of those views currently lives as it's own React component that executes on both server side and client side.  I'm starting to struggle understanding the proper way to structure the code.  </p>
  
  <p>For example, let's say <code>Profile</code> is loaded and the user clicks on "See Followers".  At that point, the dispatcher is sent a message that says <code>gotoFollowers</code>.  At the top level, we then render a whole new React component (i.e. the <code>Followers</code> component).  Unfortunately, both the <code>Follower</code> and <code>Profile</code> components requires similar data (e.g. Session data, userphoto, username, and even followers too, because we show a snippet of followers on the <code>Profile</code>).  So, it feels very wasteful to have to re-render at the top-level (including doing ajax calls) every time the user changes the page.  </p>
  
  <p>I assume I'm not doing this correctly.  Should I be using a single parent React component? (I see issues with that too) How am I supposed to structure large React applications with many views?  </p>
  
  <pre><code>window.render = function (page, id, pushState) {
    var stateURL = '';
  
    switch (page) {
      case 'Profile':
        stateURL = '/' + id;
        async.parallel({
          profileData: function (callback) { MemberLoader.load(id, callback); },
          followerData: function (callback) { FollowerLoader.load(id, callback); },
          },
          sessionData: function (callback) { Session.get(callback); },
        }, function (err, results) {
          var component = React.createFactory(Profile);
          React.render(component({ member: results.profileData, followers: results.followerData, session: results.sessionData }), mountNode);
        });
        break;
      case 'Followers':
        stateURL = '/' + id + '/followers';
        async.parallel({
          profileData: function (callback) { MemberLoader.load(id, callback); },
          sessionData: function (callback) { Session.get(callback); },
          followerData: function (callback) { FollowerLoader.load(id, callback); },
        }, function (err, results) {
          var component = React.createFactory(Followers);
          React.render(component({ member: results.profileData, followers: results.followerData, session: results.sessionData  }), mountNode);
        });
        break;
    };
  
    if (pushState) {
      window.history.pushState({ page: page, id: id }, null, stateURL);
    } else {
      window.history.replaceState({ page: page, id: id }, null, stateURL);
    }
  
  };
  
  Dispatcher.register(function(event) {
    if (event.action === 'gotoProfile') {
      window.render('Profile', event.username, true);
    } 
    else if (event.action === 'gotoFollowers') {
      window.render('Followers', event.username, false); 
    }
  });
  </code></pre>
  
  <p><strong>Note</strong>: Our application renders on both server and client side. </p>