Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@wmertens
Last active August 10, 2017 11:14
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wmertens/b581322d5212035ffe7e6b4fd6222647 to your computer and use it in GitHub Desktop.
Save wmertens/b581322d5212035ffe7e6b4fd6222647 to your computer and use it in GitHub Desktop.
Wrapper for react-router v4 with an API more to my tastes
import React, {Component, PropTypes} from 'react'
import {Link, Route as OrigRoute, Switch, Redirect, BrowserRouter as Router, withRouter} from 'react-router-dom'
// Subscribes a child to history updates, passing the current location as a prop
// This is needed to work around the React context API not updating all children
// See https://github.com/ReactTraining/react-router/issues/4629#issuecomment-284218493
export class LocationListener extends Component {
static contextTypes = {
history: PropTypes.object,
}
static propTypes = {
children: PropTypes.node,
}
state = {}
handleLocation = location => {
this.setState({location})
}
componentWillMount() {
const {history} = this.context
this.unlisten = history.listen(this.handleLocation)
}
componentWillUnmount() {
if (this.unlisten) {
this.unlisten()
}
}
render() {
const {children} = this.props
const {location} = this.state
const child = React.cloneElement(children, {location})
return child
}
}
// See https://github.com/ReactTraining/react-router/issues/4548
export const Route = ({component: Component, props, children, listen, ...rest}) => {
let r
if (props) {
// allow passing props to component
r = <OrigRoute {...rest} render={rProps => <Component {...rProps} {...props}/>}/>
} else if (children != null && typeof children !== 'function') {
// non-function children should not be rendered if no match
r = <OrigRoute {...rest} render={() => children}/>
} else {
r = <OrigRoute {...rest} component={Component}>{children}</OrigRoute>
}
return listen ? <LocationListener>{r}</LocationListener> : r
}
Route.propTypes = {
component: PropTypes.func,
props: PropTypes.object,
children: PropTypes.any,
}
export {Router, Link, Switch, Redirect, withRouter}
@wmertens
Copy link
Author

wmertens commented Mar 5, 2017

Note that github does not send notifications for comments on gists, if you post something here please also notify me via Wout.Mertens@gmail.com.

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