React-modal: Failed removeChild function for parent when parentSelector is changed

Created on 30 Jul 2019  路  6Comments  路  Source: reactjs/react-modal

Hi guys
In our project when we have player in fullscreen mode we want to show some modals on user actions. For showing modal in fullscreen I use parentSelector to change parent from body to player component. But when user leaves player in fullscreen mode with opened modal I get some error

Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.

because parent doesn't exist anymore (player) and removeChild function fails

Can be it fixed somehow? Thank you!

bug easy

Most helpful comment

Hi, I've updated to v3.11.1 and I'm still getting this error. Here's what my set up looks like:

constructor() {
    this.modalRef = React.createRef();
}
render() {
   return (
      <div className="modal-parent" ref={this.modalRef} />
      <Modal
          parentSelector={() => this.modalRef.current}
       />
    );
}

I was able to resolve it with the temp hack above but it seems like upgrading to v3.11.1 would've resolved it without the hack. Is there any additional setup I need to change? Any help would be greatly appreciated, thanks!

All 6 comments

@roman-mateush Can you make a reproducible example, please?

@roman-mateush Perhaps, you can change back the modal to the previous element before you leave fullscreen mode...or let me know if found a way to fix this.

This happens for me too. I am on 3.10.1
I have this (simplified) in my App:

// OuterParent -> Parent -> Modal
const OuterParent = props => props.show && (<Parent />)

function Parent() {
  const root = useRef(null);
  return (
    <div ref={root}>
      <Modal parentSelector={() => root.current}
    </div>
  );
}

When the Parent is unmounted from OuterParent The app crashes with error:

Screen Shot 2019-09-19 at 2 57 52 PM

Because the Parent is already unmounted and returns null when parent.removeChild get called

I had to use a hack as a temp fix

         parentSelector={() => {
              return this.root.current || {removeChild: () => {}}
         }}

Perhaps add a sanity check to removePortal is the fix

const parent = getParentElement(this.props.parentSelector);
if (parent) parent.removeChild(this.node);

@heshan0131 props.show && (<Parent />) this conditional render seems what can cause the problem, because it will unconditionaly unmount Parent when show becomes false. Than you no longer have the parent element.

Additionally to if (parent), we can add an extra log, just so we know what happened.

More info

The reason this exception will raise is that react-modal schedules the removing of the modal on setTimeout (to allow the animation to finish before removing itself), this can be enough time to the parent to be removed.

Hi, I've updated to v3.11.1 and I'm still getting this error. Here's what my set up looks like:

constructor() {
    this.modalRef = React.createRef();
}
render() {
   return (
      <div className="modal-parent" ref={this.modalRef} />
      <Modal
          parentSelector={() => this.modalRef.current}
       />
    );
}

I was able to resolve it with the temp hack above but it seems like upgrading to v3.11.1 would've resolved it without the hack. Is there any additional setup I need to change? Any help would be greatly appreciated, thanks!

Just so that no one who arrives here is confused by a typo in the above comment, v3.11.2 is the version that fixes this issue. I can confirm that

Was this page helpful?
0 / 5 - 0 ratings