Skip to content

Instantly share code, notes, and snippets.

@a-axton
Last active July 16, 2016 00:29
Show Gist options
  • Select an option

  • Save a-axton/4226517fc6e3a9f2c44cb6872bcafc22 to your computer and use it in GitHub Desktop.

Select an option

Save a-axton/4226517fc6e3a9f2c44cb6872bcafc22 to your computer and use it in GitHub Desktop.
Custom route leave
import React from 'react';
import RouteLeaveConfirmation from './RouteLeaveConfirmation';
class ExampleComponent extends React.Component {
onConfirmRouteWillLeave () {
console.log('confirmed');
}
onCancelRouteWillLeave () {
console.log('cancelled');
}
routeWillLeave (nextLocation, handleConfirmRouteWillLeave, handleCancelRouteWillLeave) {
if (condition) {
return <Modal>
<button onClick={handleCancelRouteWillLeave}>Cancel</button>
<button onClick={handleConfirmRouteWillLeave}>Continue</button>
</Modal>
}
}
render () {
return (
<div>
{this.props.routeWillLeaveComponent}
</div>
);
}
}
export default RouteWillLeaveConfirmation(ExampleComponent);
import React from 'react';
export default function wrap(WrappedComponent) {
return class RouteLeaveConfirmation extends React.Component {
static contextTypes = {
router: React.PropTypes.object.isRequired
};
constructor (props) {
super(props);
this.state = {
routeWillLeaveComponent: null,
nextLocation: null,
confirmed: false
};
this.handleConfirmRouteWillLeave = this.handleConfirmRouteWillLeave.bind(this);
this.handleCancelRouteWillLeave = this.handleCancelRouteWillLeave.bind(this);
}
componentDidMount () {
let component = this.refs.component;
this.context.router.setRouteLeaveHook(this.props.route, (nextLocation) => {
if (this.state.confirmed) { return; }
if (component.routeWillLeave) {
let showComponent = component.routeWillLeave(nextLocation, this.handleConfirmRouteWillLeave, this.handleCancelRouteWillLeave);
if (showComponent) {
this.setState({
routeWillLeaveComponent: showComponent,
nextLocation: nextLocation
});
return false;
}
return;
}
});
}
handleConfirmRouteWillLeave () {
let next = this.state.nextLocation;
let action = next.action.toLowerCase();
let router = this.context.router;
this.setState({
confirmed: true
}, () => {
if (this.refs.component.onConfirmRouteWillLeave) {
this.refs.component.onConfirmRouteWillLeave();
}
if (router[action]) {
router[action](next.pathname);
} else {
router.push(next.pathname);
}
});
}
handleCancelRouteWillLeave () {
if (this.refs.component.onCancelRouteWillLeave) {
this.refs.component.onCancelRouteWillLeave();
}
this.setState({
routeWillLeaveComponent: null,
nextLocation: null
});
}
render() {
return <WrappedComponent
ref='component'
{...this.props}
routeWillLeaveComponent={this.state.routeWillLeaveComponent}
/>;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment