Skip to content

Failed removeChild function for parent when parentSelector is changed #769

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
roman-mateush opened this issue Jul 30, 2019 · 6 comments · Fixed by #778
Closed

Failed removeChild function for parent when parentSelector is changed #769

roman-mateush opened this issue Jul 30, 2019 · 6 comments · Fixed by #778

Comments

@roman-mateush
Copy link

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!

@diasbruno
Copy link
Collaborator

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

@diasbruno
Copy link
Collaborator

@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.

@heshan0131
Copy link

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);

@diasbruno
Copy link
Collaborator

@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.

@kamillejohnson
Copy link

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!

@MadhuvanthG
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants