import React from "react";
import PropTypes from "prop-types";
import invariant from "invariant";

import RouterContext from "./RouterContext";

/**
 * The public API for prompting the user before navigating away
 * from a screen with a component.
 */
class InnerPrompt extends React.Component {
  static defaultProps = {
    when: true
  };

  enable(message) {
    if (this.unblock) {
      this.unblock();
    }

    this.unblock = this.props.router.history.block(message);
  }

  disable() {
    if (this.unblock) {
      this.unblock();
      this.unblock = null;
    }
  }

  componentDidMount() {
    invariant(
      this.props.router,
      "You should not use <Prompt> outside a <Router>"
    );

    if (this.props.when) this.enable(this.props.message);
  }

  componentDidUpdate(prevProps) {
    if (this.props.when) {
      if (!prevProps.when || prevProps.message !== this.props.message) {
        this.enable(this.props.message);
      }
    } else {
      this.disable();
    }
  }

  componentWillUnmount() {
    this.disable();
  }

  render() {
    return null;
  }
}

function Prompt(props) {
  return (
    <RouterContext.Consumer>
      {router => <InnerPrompt {...props} router={router} />}
    </RouterContext.Consumer>
  );
}

if (__DEV__) {
  Prompt.propTypes = {
    when: PropTypes.bool,
    message: PropTypes.oneOfType([PropTypes.func, PropTypes.string]).isRequired
  };
}

export default Prompt;

@@ -142,612 +142,119 @@
 %22;%0A%0A
-/**%0A * The public API for prompting the user before navigating away%0A * from a screen with a component.%0A */%0Aclass InnerPrompt extends React.Component %7B%0A  static defaultProps = %7B%0A    when: true%0A  %7D;%0A%0A  enable(message) %7B%0A    if (this.unblock) %7B%0A      this.unblock();%0A    %7D%0A%0A    this.unblock = this.props.router.history.block(message);%0A  %7D%0A%0A  disable() %7B%0A    if (this.unblock) %7B%0A      this.unblock(
+class Block extends React.Component %7B%0A  constructor(props) %7B%0A    super(props
 );%0A    
-  
 this.
-unblock = null;%0A    %7D%0A  %7D%0A%0A  componentDidMount() %7B%0A    invariant(%0A      this.props.router,%0A      %22You should not use %3CPrompt%3E outside a %3CRouter%3E%22%0A    );%0A%0A    if (this.props.when) this.enable(this.
+release = props.method(
 prop
@@ -316,56 +316,8 @@
 if (
-this.props.when) %7B%0A      if (!prevProps.when %7C%7C 
 prev
@@ -366,83 +366,81 @@
     
-  
 this.
-enable(this.props.message);%0A      %7D%0A    %7D else %7B%0A      this.disable(
+release();%0A      this.release = this.props.method(this.props.message
 );%0A 
@@ -489,14 +489,14 @@
 his.
-disabl
+releas
 e();
@@ -542,170 +542,629 @@
 %0A%7D%0A%0A
-function Prompt(props) %7B%0A  return (%0A    %3CRouterContext.Consumer%3E%0A      %7Brouter =%3E %3CInnerPrompt %7B...props%7D router
+if (__DEV__) %7B%0A  Block.propTypes = %7B%0A    method: PropTypes.func.isRequired,%0A    message: PropTypes.oneOfType(%5BPropTypes.func, PropTypes.string%5D).isRequired%0A  %7D;%0A%7D%0A%0A/**%0A * The public API for prompting the user before navigating away from a screen.%0A */%0Afunction Prompt(props) %7B%0A  return (%0A    %3CRouterContext.Consumer%3E%0A      %7Brouter =%3E %7B%0A        invariant(router, %22You should not use %3CPrompt%3E outside a %3CRouter%3E%22);%0A%0A        return props.when ? (%0A          %3CBlock method=%7Brouter.history.block%7D message
 =%7B
+p
 ro
-uter%7D /%3E%7D%0A    %3C/RouterContext.Consumer%3E%0A  );%0A%7D
+ps.message%7D /%3E%0A        ) : null;%0A      %7D%7D%0A    %3C/RouterContext.Consumer%3E%0A  );%0A%7D%0A%0APrompt.defaultProps = %7B%0A  when: true%0A%7D;
 %0A%0Aif

Refactor <Prompt> and remove <InnerPrompt>