Skip to content

Commit

Permalink
Prevent remount component on routes with the same component (#5430)
Browse files Browse the repository at this point in the history
* Prevent remount component on routes with the same component

* history dependency added

* react-router-config - 'key' prop support added to renderRoutes
  • Loading branch information
artywhite authored and timdorr committed Aug 21, 2017
1 parent 4ba8989 commit f1a600b
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 3 deletions.
1 change: 1 addition & 0 deletions packages/react-router-config/README.md
Expand Up @@ -48,6 +48,7 @@ Routes are objects with the same properties as a `<Route>` with a couple differe
- the only render prop it accepts is `component` (no `render` or `children`)
- introduces the `routes` key for sub routes
- Consumers are free to add any additional props they'd like to a route, you can access `props.route` inside the `component`, this object is a reference to the object used to render and match.
- accepts `key` prop to prevent remounting component when transition was made from route with the same component and same `key` prop

```js
const routes = [
Expand Down
@@ -1,7 +1,10 @@
import React from 'react'
import ReactDOM from 'react-dom'
import ReactDOMServer from 'react-dom/server'
import StaticRouter from 'react-router/StaticRouter'
import Router from 'react-router/Router'
import renderRoutes from '../renderRoutes'
import createHistory from 'history/createMemoryHistory'

describe('renderRoutes', () => {
let renderedRoutes
Expand Down Expand Up @@ -111,6 +114,66 @@ describe('renderRoutes', () => {
expect(renderedRoutes[0]).toEqual(routeToMatch)
expect(renderedRoutes[1]).toEqual(childRouteToMatch)
})

it('does not remount a <Route>', () => {
const node = document.createElement('div')

let mountCount = 0

const App = ({ route: { routes } }) => (
renderRoutes(routes)
)

class Comp extends React.Component {
componentDidMount() {
mountCount++
}

render() {
return <div />
}
}

const routes = [
{ path: '/',
component: App,
routes: [
{ path: '/one',
component: Comp,
key: 'comp'
},
{ path: '/two',
component: Comp,
key: 'comp'
},
{ path: '/three',
component: Comp,
}
]
}
]

const history = createHistory({
initialEntries: [ '/one' ]
})

ReactDOM.render((
<Router history={history}>
{renderRoutes(routes)}
</Router>
), node)

expect(mountCount).toBe(1)

history.push('/one')
expect(mountCount).toBe(1)

history.push('/two')
expect(mountCount).toBe(1)

history.push('/three')
expect(mountCount).toBe(2)
})
})

describe('routes with exact', () => {
Expand Down
12 changes: 9 additions & 3 deletions packages/react-router-config/modules/renderRoutes.js
Expand Up @@ -5,9 +5,15 @@ import Route from 'react-router/Route'
const renderRoutes = (routes, extraProps = {}) => routes ? (
<Switch>
{routes.map((route, i) => (
<Route key={i} path={route.path} exact={route.exact} strict={route.strict} render={(props) => (
<route.component {...props} {...extraProps} route={route}/>
)}/>
<Route
key={route.key || i}
path={route.path}
exact={route.exact}
strict={route.strict}
render={(props) => (
<route.component {...props} {...extraProps} route={route}/>
)}
/>
))}
</Switch>
) : null
Expand Down
1 change: 1 addition & 0 deletions packages/react-router-config/package.json
Expand Up @@ -41,6 +41,7 @@
"eslint-plugin-import": "^1.15.0",
"eslint-plugin-react": "^5.2.2",
"gzip-size": "^3.0.0",
"history": "^4.6.3",
"jest": "^20.0.4",
"pretty-bytes": "^3.0.1",
"react": "^15.4.2",
Expand Down

0 comments on commit f1a600b

Please sign in to comment.