Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A replacement component for the react-router `Prompt`.
import React from 'react';
import {withRouter} from 'react-router-dom';
import PropTypes from 'prop-types';
/**
* A replacement component for the react-router `Prompt`.
* Allows for more flexible dialogs.
*
* @example
* <NavigationPrompt when={this.props.isDirty}>
* {(isOpen, onConfirm, onCancel) => (
* <Modal show={isOpen}>
* <div>
* <p>Do you really want to leave?</p>
* <button onClick={onCancel}>Cancel</button>
* <button onClick={onConfirm}>Ok</button>
* </div>
* </Modal>
* )}
* </NavigationPrompt>
*/
class NavigationPrompt extends React.Component
{
constructor(props) {
super(props);
this.state = {nextLocation: null, openModal: false};
this.onCancel = this.onCancel.bind(this);
this.onConfirm = this.onConfirm.bind(this);
}
componentDidMount() {
this.unblock = this.props.history.block((nextLocation) => {
if (this.props.when) {
this.setState({
openModal: true,
nextLocation: nextLocation
});
}
return !this.props.when;
});
}
componentWillUnmount() {
this.unblock();
}
onCancel() {
this.setState({nextLocation: null, openModal: false});
}
onConfirm() {
this.navigateToNextLocation();
}
navigateToNextLocation() {
this.unblock();
this.props.history.push(this.state.nextLocation.pathname);
}
render() {
return (
<div>
{this.props.children(this.state.openModal, this.onConfirm, this.onCancel)}
</div>
);
}
}
NavigationPrompt.propTypes = {
when: PropTypes.bool.isRequired,
children: PropTypes.func.isRequired,
};
export default withRouter(NavigationPrompt);
@akrigline

This comment has been minimized.

Copy link

commented Aug 25, 2017

When I use my browser's Back button, the modal pops up for a split second and then immediately disappears. Is this something history.block can't handle well?

@ZacharyRSmith

This comment has been minimized.

Copy link

commented Feb 8, 2018

@akrigline, we have (a little) more info on your issue here

tl;dr: we still don't know what causes it, but it happens with some setups but not others. @cumibulat was able to reproduce when using react-boilerplate but did not reproduce when not using react-boilerplate

@ZacharyRSmith

This comment has been minimized.

Copy link

commented Mar 3, 2018

FYI to readers, I've published an adaptation of this to npm: https://www.npmjs.com/package/react-router-navigation-prompt

@aliwaheed51

This comment has been minimized.

Copy link

commented Aug 9, 2018

Could You please share any live example of that?

@QuantumInformation

This comment has been minimized.

Copy link

commented Apr 3, 2019

What's wrong with the original Prompt?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.