question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

unmountComponentAtNode works async ?

See original GitHub issue

Do you want to request a feature or report a bug?

bug

What is the current behavior?

i tried to use ReactDOM.unmountComponentAtNode and ReactDOM.render to manage my multi roots. i found that if i use them in sync code, i get an error just like this when i change route pages:

Warning: unmountComponentAtNode(): The node you're attempting to unmount was rendered by React and is not a top-level container. Instead, have the parent component update its state and rerender in order to remove this component.
Warning: render(...): Replacing React-rendered children with a new root component. If you intended to update the children of this node, you should instead have the existing children update their state and render the new components instead of calling ReactDOM.render.

i use browserHistory to change route. my code is written in componentDidMount method of a root React component:

Page1.js

  componentDidMount() {
    const a = document.getElementById('root2');
    ReactDOM.unmountComponentAtNode(a);
    ReactDOM.render(
      <A />,
      a
    );
    ReactDOM.render(
      <B />,
      document.getElementById('root3')
    );
  }

Page2.js

  componentDidMount() {
    const a = document.getElementById('root2');
    ReactDOM.unmountComponentAtNode(a);
    ReactDOM.render(
      <C />,
      a
    );
    ReactDOM.render(
      <B />,
      document.getElementById('root3')
    );
  }

And then, if i use setTimeout to wrap ReactDOM.render after ReactDOM.unmountComponentAtNode(a);, the result can be success.

What is the expected behavior?

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

react 16.5.2 react-dom 16.5.2

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:1
  • Comments:12 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
AyWacommented, Sep 24, 2018

Hello,

I tried to investigate with the example that you gave. (but note that It is the first time I am checking reactDOM source and just want to try to contribute in react 😃)

So first, to do what you want to achieve: you do not need to call unmountComponentAtNode if you just plan to render/rerender a react component.

  • In case of rendering the same component => it will just rerender properly (without unmount / mount a new component)
  • In case of rendering an other component => it will properly unmount the previous component and render the new one.

You can easily test those 2 behavior by:

  • removing ReactDOM.unmountComponentAtNode(ele)
  • adding: componentWillUnmount() {console.log("unmount")} in component 2/1 and check that the behavior is correct 😉

However I think the code that you share should work correctly and this my investigation:

bug behavior

  • first button click -> ReactDOM.unmountComponentAtNode(ele) unmount something empty -> it return false which is the correct behavior (from the doc): false if there was no component to unmount.
  • component 1 is render correctly and _reactRootContainer is set correctly
  • second button click -> ReactDOM.unmountComponentAtNode(ele) unmount a react component -> it return true which is the correct behavior (from the doc): Returns true if a component was unmounted
  • component 2 is render -> component 1 is unMount ->_reactRootContainer will be set to null for the container (which is the bug)
  • next click, ReactDOM.unmountComponentAtNode(ele) will have some error and return false, and will not unmount correctly component 2. The root cause of that is _reactRootContainer which is null.

I guess the root cause might come from https://github.com/facebook/react/blob/144328fe81719e916b946e22660479e31561bb0b/packages/react-dom/src/client/ReactDOM.js#L684 + the uncorrect order of unmount / mount ?

If we wrap all the code in async, it will works because the order will be: component 1 is unMount -> _reactRootContainer will be set to null -> component 2 is render -> _reactRootContainer is correctly set

I used https://codesandbox.io/s/7wvwlnorn6 to investigate.

Let me know If it needs a fix or not, or if the investigation is wrong.

1reaction
AyWacommented, Sep 27, 2018

@gaearon I could reproduce with unit test and tried to find a correct way to fix. (I found multiple way, but not really confident about the quality of those, seems quite hacky)

PR is there https://github.com/facebook/react/pull/13744 any feedback / opinion about the proposal to make fix would be appreciated 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Trying to use `unmountComponentAtNode` from react-dom ...
I was trying to remove an element from the DOM and tried using unmountComponentAtNode because I was still registering click events some how....
Read more >
ReactDOM – React
findDOMNode only works on mounted components (that is, components that have been placed in the DOM). If you try to call this on...
Read more >
react-dom unmountComponentAtNode TypeScript Examples
This page shows TypeScript code examples of react-dom unmountComponentAtNode.
Read more >
Can someone explain in the most layman terms possible what ...
... in the most layman terms possible what unmountComponentAtNode' does?- ... can someone explain to me how the async works in this scenario...
Read more >
What is the purpose of unmountComponentAtNode method?
This method is available from react-dom package and it removes a mounted React component from the DOM and clean up its event handlers...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found