As noted in other answers, this is handled by the render prop, which gives the example:
<Route path="/home" render={() => <div>Home</div>}/>
However, I (and many others) find this syntax pretty ugly. In the original issue on prop passing with Route, there's a well-liked wrapper which I wanted to surface, I've made some improvements and propose this terse and effective wrapper:
const PropsRoute = ({component, path, ...otherProps}) => (
<Route {...otherProps} path={path} render={routeProps =>
React.createElement(component, {...otherProps, ...routeProps})
} />
)
This can be used as might be expected:
<Router>
<main>
<PropsRoute exact path="/" component={Home} auth={this.state.auth} />
</main>
</router>
Note that doing this will pass the Route props down to the component. Any prop passed to Route that isn't 'component' or 'path' will be passed down to the component. In this formulation, any routeProps (passed by the react-router) will override custom props passed via this syntax.
This can then be quite easily expanded on to make the common login pattern:
const AuthedRoute = ({auth, ...props}) =>
!auth.valid()? <Redirect to="/login" />: <PropsRoute {...{...props, auth: auth}} />;
Edit: I've largely abandoned this approach as of 2019, in favour of something like this:
<Route {...{
path: "/path/to/component",
render: ({ location }) => <MyComponent {...{
location
}}/>
}}/>
This can appear a bit more gnarly, but it makes deeply nested render trees much clearer, and lets you use full Javascript in your JSX parameters.