andreypopp/react-router-component — pull request #46 by matthewwithanm (2014-04-15 21:34:38+00:00)
Title: onDispatch callback and connect middleware

This PR has two additions, though the first is really only a means to the second.

Firstly, it adds an `onDispatch` callback. This is basically the same as `onNavigation`, but it's also called on `componentDidMount`.

The second, and main addition, is a connect middleware. It works like this:

```javascript
var reactRouter = require('react-router-component/lib/contrib/connect-middleware');

// ...create app...

app.use(reactRouter(MyRouterComponent));
```

Your node app will now use RRC to route requests, sending the appropriate status code! (404 or 200)

By default, it adds an HTML doctype and serves the app as "text/html", however, this can be customized with a second argument:

```javascript
app.use(reactRouter(MyRouterComponent, {doctype: 'svg'})); // Shortcut doctypes
app.use(reactRouter(MyRouterComponent, {doctype: ''})); // Long doctypes
app.use(reactRouter(MyRouterComponent, {contentType: 'application/xhtml+xml'})); // Guess doctype based on content type
```

etc.

You can also pass props:

```javascript
app.use(reactRouter(MyRouterComponent, {props: {someProp: 'hello'}}));
```

@andreypopp I'm not sure how this plays with asynchronous components. Do you think you could take a look at that?

Though it can happen post-merge IMO, I think we need to continue to make it easier to create router components. The 1.x branch has been heading that direction already, but it's not quite there yet. Here's what a minimal "App" looks like now:

```javascript
var App = React.createClass({
mixins: [RoutingEnvironmentMixin],
renderRouter: function() {
return ...;
},
match: function(url) {
return this.renderRouter().match(url);
},
render: function() {
return (

...

{ this.renderRouter() }

);
}
});
```

A lot of this is boilerplate I really want to get rid of. (Technically, I guess there is a more minimal example if you're willing to make your real router your top-level component instead of putting it in the body.) Also, having to create the router in match…well, sucks.

Still, I'm super psyched about being able to bridge the gap between my server and React app so easily—and to have React driving the process!