-
Notifications
You must be signed in to change notification settings - Fork 46.9k
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
Reset lastEffect when resuming SuspenseList #18412
Conversation
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit a86b002:
|
We store an effect pointer so we can backtrack in the effect list in some cases. This is a stateful variable. If we interrupt a render we need to reset it. This field was added after the optimization was added and I didn't remember to reset it here. Otherwise we end up not resetting the firstEffect so it points to a stale list. As a result children don't end up inserted like we think they were. Then we try to remove them it errors. It would be nicer to just get rid of the effect list and use the tree for effects instead. Maybe we still need something for deletions tho.
00c5575
to
a86b002
Compare
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 don't understand it but I trust you this works
() => updateHighPri(true), | ||
); | ||
|
||
// That will intercept the previous render. |
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.
interrupt? :-)
// First attempt at high pri. | ||
'Suspend! [A]', | ||
'Loading A', | ||
// Re-render at forced. |
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.
What does "forced" mean here? Which branch does it correspond to? Explain like I'm five.
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.
SuspenseList sets the suspense context that during render “forces” the suspense boundary into fallback state.
In this case it’s only one boundary so it doesn’t need to but we don’t know. If there was another boundary in the row we would have to rerender that one so that’s the second pass.
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.
Ohh that makes sense! I didn’t realize it works this way.
// Re-render at forced. | ||
'Suspend! [A]', | ||
'Loading A', | ||
// We auto-commit this on DEV. |
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.
Why? "Flush fallbacks" flag?
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.
Yea
'Suspend! [A]', | ||
'Loading A', | ||
] | ||
: [ |
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.
This test is verifying the same logs appear three or four times. But how do we know the comments are actually telling the truth? Can we include the boolean values in logs so that we know we're actually rendering at the priority suggested by comments?
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’d rather just delete this assertion. It’s unrelated. It’s just that Scheduler expects force me to assert. This is super suboptimal so it’ll change by heuristics a lot.
We store an effect pointer so we can backtrack in the effect list in some cases. This is a stateful variable. If we interrupt a render we need to reset it.
This field was added after the optimization was added and I didn't remember to reset it here.
Otherwise we end up not resetting the firstEffect so it points to a stale list. As a result children don't end up inserted like we think they were. Then we try to remove them it errors.
It would be nicer to just get rid of the effect list and use the tree for effects instead. Maybe we still need something for deletions tho.