-
Notifications
You must be signed in to change notification settings - Fork 46.8k
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
bailoutOnLowPriority
pushes context to mirror complete phase context pop
#8590
Conversation
It feels counter-intuitive to me that despite bailout in Even if it works today, it's a bit hard to write |
if (workInProgress.tag === HostPortal) { | ||
pushHostContainer(workInProgress.stateNode.containerInfo); | ||
switch (workInProgress.tag) { | ||
case ClassComponent: |
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.
If we do this I think we should handle HostComponent
here too for consistency.
It also gets popped unconditionally in complete
phase.
This defensive check is likely why it didn't break so far but we can replace it with an assertion.
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.
+1 from me for replacing with an assertion.
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.
Sorry. I missed this comment. Let me add an assertion, as you say! 😄
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.
Accepting if you:
-
Follow up with @sebmarkbage to ensure that running
complete
afterbegin
bailed is intentional and there are good reasons for this in the first place. -
If the above is true, please also fix
HostComponent
in the same way and try to remove the defensive check in host context code. -
Try to figure out why we hit the bailout code in the first place in RN. We didn't enable deferred mode by default, did we? Then I don't understand why bailout happened.
If I'm not mistaken, the conceptual model for bailing out is memoization, and the conceptual model for the |
Relatedly, if I'm recalling a conversation with @sebmarkbage correctly, a lot of the stuff we're doing in |
I would like these branches to be unified: It's too easy to mess them up right now. |
I think I asked this already, but is there any case where you don't push context for a context provider in the |
I tried handling
As of this PR, we always push- even if we return early for |
RE: @gaearon
Done. Sebastian confirmed that this is intentional.
Calling
If a |
Sounds good. Any objections to unifying this logic per #8590 (comment)? Like extract them in a single function since it looks like we need to do exact same thing in both cases. |
If we always push it should be moved to the switch statement here. https://github.com/bvaughn/react/blob/ed3debfbe2a3d446ddc8755e6013238d4b812ca2/src/renderers/shared/fiber/ReactFiberBeginWork.js#L531 |
I don't get it, why? If we move it there it won't push on bailout. Don't we want to push on bailout per this thread? |
No objections, really. I'm just less confident about the scope of such a change since I haven't tested it yet (and I'm still learning my way around this code). I can make a pass at doing that.
We can't because in some cases we bailout before that line is reached. |
Oh pssh don't mind me. Still seems weird that we're pushing in different places. OTOH don't want to perform the check for all components, just ones that are possible context providers. So ok. I just wish the logic were more centralized. |
Replacing the matching fiber check in Should I block this PR on that? Or back out the At the moment, I've added a new TODO comment there linking to this PR thread. |
…rror complete phase context pop
4fcd840
to
441cc5c
Compare
Oh okay. It doesn't work because then we would have to check if something was a context provider before we pop. Currently we pop without checks because it's faster. And checking twice seems like useless work. |
Maybe we can add a |
4e31116
to
b22c673
Compare
Does this warning fail when you "forget" to push? |
I think this warning triggers when you pop context for a |
The warning appears working to me. It fails in some (new) cases—I'll send you a PR. |
Okay, I sent a PR against your branch: bvaughn#1. |
I don't want to block you on this but it would be great to fix all context bugs together. So if my fix in bvaughn#1 doesn't work I'd appreciate if you could take the test I added in there and fix it some other way. |
I don't mind, so long as things like the Calendar tool bug Tom reported can wait on me to write a few more tests! 😁 |
Let's merge just the change to how non-host context works to keep this focused then. I have a work-in-progress branch trying to address other issues so I can submit it later against master. |
Roger that. Let me know if you'd like any help writing test cases for your follow-up. I thought a little about how I might write some last night. |
b22c673
to
441cc5c
Compare
These are a start: #8593 |
While testing the new
ReactNativeFiber
renderer on internal apps, I discovered that the Ads Manager app as well as the "App - UIExplorer Browser" component inside of Catalyst both threw the an "Unexpected context pop" error. I traced the root cause of this error to the fact that in the complete phase we always pop context for context providers but in the begin phase we don't always push. (Specially if we bailout on low priority we don't push.) This causes us to pop too many times in certain cases.This PR corrects the behavior, making push/pop mirror each other, and adds a unit test that verifies the fix. Both Ads Manager and "App - UIExplorer Browser" function correctly once this fix is in place.
cc @acdlite to review since we spoke about this briefly and you have some context (heh) about the problem.
cc @gaearon as well since I think you implemented this stuff initially?