react-portal icon indicating copy to clipboard operation
react-portal copied to clipboard

Using state to conditionally render components causing PortalWithState modal to close when closeOnOutsideClick true

Open davidjamescarter opened this issue 7 years ago • 2 comments

I have found that when using the PortalWithState with closeOnOutsideClick my modal will close when using state to conditionally render components.

PortalWithState closeOnOutsideClick closeOnEsc defaultOpen>
    {({ closePortal, portal }) =>
        portal(
        <Modal closePortal={closePortal} key="confirmation-modal">
            <JobPreviewModal
            bid={bid}
            jobOffer={jobOffer}
            schedule={schedule}
            taxonomiesByClassification={taxonomiesByClassification}
            />
        </Modal>,
        )
    }
</PortalWithState>`
class JobPreviewModal extends PureComponent {
  state = {
    editing: false,
    some: false,
  };

  toggleEditingState = () => {
    this.setState(previousState => {
      return {
        editing: !previousState.editing,
        some: !previousState.some,
      };
    });
  };

  render() {
    const { jobOffer, bid, schedule, taxonomiesByClassification } = this.props;

    const { editing } = this.state;

    return !editing ? (
      <JobPreview
        bid={bid}
        jobOffer={jobOffer}
        schedule={schedule}
        taxonomiesByClassification={taxonomiesByClassification}
        toggleEditingState={this.toggleEditingState}
      />
    ) : (
      <h1>Editing</h1>
    );
  }
}
class Modal extends Component {
  render() {
    const { children, closePortal, small } = this.props;

    console.log('children', children);
    return (
      <ModalWrapper small={small}>
        <div>
          {children.length
            ? children.map(child => React.cloneElement(child))
            : React.cloneElement(children)}
          <button className="close" onClick={closePortal}>
            Close
          </button>
        </div>
      </ModalWrapper>
    );
  }
}

Changing state to edit: true. Causes modal to close.

Has anyone else experienced, have a fix? Going to see if I can figure out a fix locally and PR if so.

davidjamescarter avatar Jan 23 '19 12:01 davidjamescarter

I've found setting closeOnOutsideClick and triggering openPortal doesn't open the portal at all..

mikkelwf avatar Feb 05 '19 13:02 mikkelwf

@davidcarter-me i might have a solution for you.

When you click stuff inside the portal, changing state on a parent element causes a render on the click target. When this event bubbles to the Portal, the contains check inside the portals closeOnOutsideClick cannot reference the e.target

I worked around this by wrapping the state changing method in requestAnimationFrame, so the closeOnOutsideClick resolver runs first, and then the state change.

Hope that helps

mikkelwf avatar Feb 07 '19 13:02 mikkelwf