mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
Force unwind work loop during selective hydration (#25695)
When an update flows into a dehydrated boundary, React cannot apply the update until the boundary has finished hydrating. The way this currently works is by scheduling a slightly higher priority task on the boundary, using a special lane that's reserved only for this purpose. Because the task is slightly higher priority, on the next turn of the work loop, the Scheduler will force the work loop to yield (i.e. shouldYield starts returning `true` because there's a higher priority task). The downside of this approach is that it only works when time slicing is enabled. It doesn't work for synchronous updates, because the synchronous work loop does not consult the Scheduler on each iteration. We plan to add support for selective hydration during synchronous updates, too, so we need to model this some other way. I've added a special internal exception that can be thrown to force the work loop to interrupt the work-in-progress tree. Because it's thrown from a React-only execution stack, throwing isn't strictly necessary — we could instead modify some internal work loop state. But using an exception means we don't need to check for this case on every iteration of the work loop. So doing it this way moves the check out of the fast path. The ideal implementation wouldn't need to unwind the stack at all — we should be able to hydrate the subtree and then apply the update all within a single render phase. This is how we intend to implement it in the future, but this requires a refactor to how we handle "stack" variables, which are currently pushed to a per-render array. We need to make this stack resumable, like how context works in Flight and Fizz.
This commit is contained in:
@@ -445,5 +445,6 @@
|
||||
"457": "acquireHeadResource encountered a resource type it did not expect: \"%s\". This is a bug in React.",
|
||||
"458": "Currently React only supports one RSC renderer at a time.",
|
||||
"459": "Expected a suspended thenable. This is a bug in React. Please file an issue.",
|
||||
"460": "Suspense Exception: This is not a real error! It's an implementation detail of `use` to interrupt the current render. You must either rethrow it immediately, or move the `use` call outside of the `try/catch` block. Capturing without rethrowing will lead to unexpected behavior.\n\nTo handle async errors, wrap your component in an error boundary, or call the promise's `.catch` method and pass the result to `use`"
|
||||
"460": "Suspense Exception: This is not a real error! It's an implementation detail of `use` to interrupt the current render. You must either rethrow it immediately, or move the `use` call outside of the `try/catch` block. Capturing without rethrowing will lead to unexpected behavior.\n\nTo handle async errors, wrap your component in an error boundary, or call the promise's `.catch` method and pass the result to `use`",
|
||||
"461": "This is not a real error. It's an implementation detail of React's selective hydration feature. If this leaks into userspace, it's a bug in React. Please file an issue."
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user