The source code tells the difference:
if (component)
return match ? React.createElement(component, props) : null
if (render)
return match ? render(props) : null
When you use component
prop, the component is instantiated per every call of Route#render
. It means that, for your component that you pass to component
prop of Route, constructor, componentWillMount
, and componentDidMount
will be executed every time the route is rendered.
For example, if you have
<Route path="/:locale/store" component={Store} />
and the user navigates to /en/store, then goes elsewhere, and then navigates back to /en/store, the Store component will be mounted, then unmounted, and then mounted again. It is similar to doing
<Route path="/:locale/store">
<Store />
</Route>
Compared to that, if you use render
prop, the component is evaluated on every Route#render
. Remember that every component is a function? This function will be executed as is, without any lifecycle methods. So when you have it like
<Route path="/:locale/store" render={Store} />
you can think of it as
<Route path="/:locale/store">
{Store()}
</Route>
It saves you runtime because no lifecycle methods are run, but it also has a downside in case Store component has some post-mount lifecycle methods like shouldComponentUpdate that may increase performance as well.
There was a good post on Medium about this performance hack, please take a look at it. It’s written very well and is applicable to React 16, too.