-
Notifications
You must be signed in to change notification settings - Fork 49.9k
ReactRootContainer should not be set to null if root has been rerender #13744
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
ReactRootContainer should not be set to null if root has been rerender #13744
Conversation
| callback, | ||
| ); | ||
| } else { | ||
| if (root.shouldBeUnMount && children != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Flow will fail there, but waiting to get Proposal of fix: opinion
Details of bundled changes.Comparing: 2c7b78f...4bdf2e7 scheduler
Generated by 🚫 dangerJS |
| function Parent() { | ||
| ReactDOM.render(<App1 />, containerApp); | ||
| ReactDOM.unmountComponentAtNode(containerApp); | ||
| ReactDOM.render(<App2 />, containerApp); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't say this is a supported way to use React. There shouldn't be side effects in the rendering phase.
Can you come up with a repro case that is more valid? e.g. maybe you can reproduce this with a class component when calling render and unmountComponentAtNode inside componentDidMount or another lifecycle?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, the original issue was with componentDidMount so I updated the test with it.
Also I don't know if it should be supported or just throw a warnings? (because in the original issue, the unmountComponentAtNode was unnecessary).
Follow up to #13690
Detail about the issue:
render/unmountComponentAtNodeinside an other life cycle that accept side effect likeComponentDidMount, it is queue in order to prevent reentrancy from https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactFiberScheduler.js#L1982DOMContainer, we have, anunmountComponentAtNodefollow by arender, they will be queue correctly (as explain just before)renderwill be correctly executed after theunmount. However because callback are executed at the end of thecommitLifeCycleswe will execute theunmountComponentAtNodeeven if a render has been executed, and so we will set the_reactRootContainerto null. Obviously there is multiple side effect, like nextunmountComponentAtNodemight fail or we will not execute correctly all the lifecycle etc.Proposal of fix:
As far as I know, the life cycle seems to be fine, the only problem is because callback are call in the end, we need a way to "invalidate" the
unmountComponentAtNodecallbacksolution 1 2ee1335 -> just a big hack -> because we are just checking if the container has a child element -> just made for fix purpose and can be easily broken (if component return null)
solution 2 current commit -> one way to do could be to mutate
_internalRootwith a boolean likerootShouldBeUnmount(need bettername) and then if a render happen after the unmount call we set the boolean to false again -> still feel hackysolution 3 could be just better to remove the callback if unmount root ? but for now we don't track if the function is the unMount one or not. (we can add property isUnmountRoot etc but doesn't know if it is better)
any better idea to experiment ?