Skip to content

Instantly share code, notes, and snippets.

@jbraithwaite
Forked from gaelollivier/ControlledRouter.js
Last active October 19, 2016 01:22
Show Gist options
  • Select an option

  • Save jbraithwaite/4c4ecfbc8a09d63e83d86c6810e0ec77 to your computer and use it in GitHub Desktop.

Select an option

Save jbraithwaite/4c4ecfbc8a09d63e83d86c6810e0ec77 to your computer and use it in GitHub Desktop.
React Router v4 ControlledRouter
// Code taken from:
// https://gist.github.com/gaelduplessix/050e5cce31f9fabb1030f4ba47663db5
// gaelduplessix/ControlledRouter.js
import React, { Component } from 'react'
import BrowserHistory from 'react-history/BrowserHistory'
import { Push } from 'react-history'
import { StaticRouter } from 'react-router'
class RouterWrapper extends Component {
componentWillReceiveProps(nextProps) {
const { setLocation, historyLocation, update } = nextProps;
if (update){
setLocation(historyLocation);
}
}
render() {
return this.props.children
}
}
/**
* ControlledRouter, greatly inspired by https://gist.github.com/donnanicolas/3d76397a92551f449637590bf0413133
* Usage:
* <ControlledRouter location={location} setLocation={setLocation}>
* <App />
* </ControlledRouter>
*/
class ControlledRouter extends Component {
constructor(props) {
super(props)
this.prevPathname = ''
}
shouldComponentUpdate(nextProps, nextState) {
return nextProps.location.pathname !== this.props.location.pathname;
}
componentDidUpdate() {
// Scroll to the top left on page changes
if (window && window.scrollY) {
window.scroll(0, 0);
}
}
render() {
const { location, setLocation, children } = this.props
return (
<BrowserHistory>
{({ history, action, location: historyLocation }) => {
const historyPathname = historyLocation.pathname
const controlledPathname = location.pathname
const pathChanged = historyPathname !== controlledPathname
const shouldUpdateState = pathChanged && historyPathname !== this.prevPathname
const shouldUpdateHistory = pathChanged && !shouldUpdateState
// Keep track of previous pathname
this.prevPathname = historyLocation.pathname
return (
<RouterWrapper setLocation={setLocation} historyLocation={historyLocation} update={shouldUpdateState}>
<StaticRouter
action={action}
location={historyLocation}
onPush={history.push}
onReplace={history.replace}
blockTransitions={history.block}
>
{ shouldUpdateHistory ? <Push path={location.pathname} /> : children }
</StaticRouter>
</RouterWrapper>
);
}}
</BrowserHistory>
)
}
}
ControlledRouter.displayName = 'ControlledRouter'
export default ControlledRouter;
@jbraithwaite
Copy link
Copy Markdown
Author

Remove the setTimeout which was causing bugs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment