message: frontend: Simplify createModalLauncher()
  Merge ModalWrapper into createModalLauncher() and remove all component
  state. This fixes React warnings due to the modal trying to access
  properties of a nullified synthetic event.
diff: @@ -4,17 +4,32 @@ import Modal from 'react-modal';
  import { ButtonBar, ErrorMessage } from '../utils';
  -export const createModalLauncher = (Component) => (props) => {
  +export const createModalLauncher = (Component) => (props = {}) => {
  const modalContainer = document.getElementById('modal-container');
  - const result = new Promise((resolve, reject) => {
  - const wrapper = <ModalWrapper
  - Component={Component}
  - componentProps={props || {}}
  + const result = new Promise(resolve => {
  + const closeModal = e => {
  + // Disable closing the modal with the escape key for "blocking" modals
  + if (props.blocking && _.get(e, 'type') === 'keydown') {
  + return;
  + }
  + ReactDOM.unmountComponentAtNode(modalContainer);
  + resolve();
  + };
  +
  + ReactDOM.render(<Modal
  isOpen={true}
  - resolve={resolve}
  - reject={reject} />;
  - ReactDOM.render(wrapper, modalContainer);
  + contentLabel="Modal"
  + onRequestClose={closeModal}
  + className="co-modal"
  + overlayClassName="co-overlay"
  + shouldCloseOnOverlayClick={!props.blocking}>
  + <div className="modal-dialog">
  + <div className="modal-content">
  + <Component {...props} cancel={closeModal} close={closeModal} />
  + </div>
  + </div>
  + </Modal>, modalContainer);
  });
  return {result};
  };
  @@ -44,69 +59,3 @@ ModalSubmitFooter.propTypes = {
  message: React.PropTypes.string,
  submitText: React.PropTypes.node.isRequired,
  };
  -
  -export class ModalWrapper extends React.Component {
  - constructor(props) {
  - super(props);
  - this.state = {
  - isModalOpen: this.props.isOpen,
  - };
  -
  - this.openModal = this.openModal.bind(this);
  - this.closeModal = this.closeModal.bind(this);
  - this.dismissModal = this.dismissModal.bind(this);
  - this.cleanupDOM = this.cleanupDOM.bind(this);
  - }
  -
  - cleanupDOM() {
  - ReactDOM.unmountComponentAtNode(ReactDOM.findDOMNode(this).parentNode);
  - }
  -
  - openModal() {
  - this.setState({ isModalOpen: true });
  - }
  -
  - closeModal(e) {
  - // Disable closing the modal with the escape key for "blocking" modals
  - if (this.props.componentProps.blocking && _.get(e, 'type') === 'keydown') {
  - return;
  - }
  - this.setState({ isModalOpen: false });
  - this.cleanupDOM();
  - this.props.resolve();
  - }
  -
  - dismissModal() {
  - this.setState({ isModalOpen: false });
  - this.cleanupDOM();
  - this.props.reject();
  - }
  -
  - componentWillReceiveProps(nextProps) {
  - this.setState({
  - isModalOpen: nextProps.isOpen
  - });
  - }
  -
  - componentWillUnmount() {
  - this.cleanupDOM();
  - }
  -
  - render() {
  - const {componentProps, Component} = this.props;
  -
  - return <Modal
  - isOpen={this.state.isModalOpen}
  - contentLabel="Modal"
  - onRequestClose={this.closeModal}
  - className="co-modal"
  - overlayClassName="co-overlay"
  - shouldCloseOnOverlayClick={!componentProps.blocking}>
  - <div className="modal-dialog">
  - <div className="modal-content">
  - <Component {...componentProps} cancel={this.closeModal} close={this.closeModal} />
  - </div>
  - </div>
  - </Modal>;
  - }
  -}
  