-
Notifications
You must be signed in to change notification settings - Fork 48.6k
Obscure DOMChildrenOperations error when doing multiple updates #1147
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
Comments
Wow, it really was a bug. Narrowed it down a little, but it's still rediculously "complex". Big props to @fforw for repro! Anyway, just glancing at the code and from experience, I can safely assume that the issue is that However, when taking another peek at the code, I'm pretty sure that the issue is that In practice this means that whenever But I'm 95% sure that this is what's happening, and the repro does have all the ingredients. |
Speaking a bit to @spicyj in chat, I feel like the issue is that |
http://jsbin.com/caxipewo/4/edit Apparently |
http://jsbin.com/caxipewo/6/edit Narrowed it down even further, apparently it breaks immediately on the first I still don't feel any more enlightened on the issue though... |
@syranide Your latest two jsbins (4 & 6) throw different error for me (from
And, if one removes Z from A |
@plievone Yeah different error, but I'm sure the cause is the same. The issue is the span not actually ever being rendered, just that in the old repro it doesn't actually turn into an error until later. |
@syranide Ok, so perhaps here's a reduced test case, see console: |
@plievone Huh? It does end up being rendered in your test case, and there's no error? |
@syranide, no I didn't want to throw the error so that you can see that the componentDidUpdate will be called double. The point is that first the span is not there and if one would try to access it (as in your ref.getDOMNode()) it would throw. See console for flow. |
@plievone |
@syranide Yes, there is definitely a problem there as you said, sorry for not being clear. I just wanted to reduce it so that there are no refs or forceUpdates which may bring other problems. One could throw the error in componentDidUpdate for clarity, as the innerHTML is definitely empty where it should not be. But it is interesting that it will be called right away again, and then the span will be there. |
With this, multiple setState calls triggered by a componentDidUpdate handler (or similar) will be batched together, regardless of if the original setState call was in a batching context. I also cleaned up some inconsistencies with the order of component updates and callbacks in situations where one component's update directly causes another to update. Fixes facebook#1147. Helps with facebook#1353 and facebook#1245 as well, though doesn't completely fix them yet. Test Plan: grunt test
Fixes facebook#1147. This now forces all DOM operations for a subtree to be applied when the calling `setState` or `React.renderComponent` call returns (when updates aren't being batched). This means that we can't batch innerHTML setting across different component hierarchies, but our strategy for doing so before seems flawed. It could be possible to make the old way work but it would require making setState always async even when batching isn't in play and refactoring DOMChildrenOperations to not be confused by multiple updates to the same node.
This throws
TypeError: Cannot call method 'removeChild' of null
.http://jsbin.com/caxipewo/1/edit
Maybe this can be simplified some more but this was the simplest repro I could make.
Thanks @fforw for sending a repro case over.
The text was updated successfully, but these errors were encountered: