dillon1000/react
Commit
Browse files Fix scheduler control flow (#10015)
* Use performFailedUnitOfWork instead of beginFailedWork and completeUnitOfWork separately. Also, we unwind the context stack *before* beginning work again. * Only use error loop directly after a commit We have a special, forked version of work loop that checks if a fiber is in a failed state (needs to be unmounted). This is only relevant right after a commit -- begin phase errors are handled differently, by unwinding the stack. Also renamed findNextUnitOfWork to resetNextUnitOfWork and made it a void function to signal that it's impure. * Reset nextUnitOfWork after every commit * Include the error boundary when unwinding a failed subtree Also added a warning to the error boundary to show that it failed. * Push context providers in beginFailedWork to avoid push/pop mismatch Added a test that demonstrates how an error boundary that is also a context provider could pop its context too many times if you neglect to push it in beginFailedWork. This happens because we've already popped the context once in unwindContext. The solution is a code smell. I don't like how we push/pop context in so many places. Shouldn't they all happen in the same location? * Refactor work loop - Optimizes the normal, non-error path by reducing the number of checks needed to begin performing work. - Prevents control flow from oscillating between fast normal loop and slower error loop. * Improve context unwinding test Tests that we correctly unwind an error boundary that is also a context provider. * Triangle tester should assert the tree is consistent after every action ...not just at the end. * Better implementation of infinite loop error Infinite loops should only be possible if a while loop never terminates. Now that we've refactored to avoid oscillation between different work loops, we can count updates local to each loop. The two loops that could infinite loop are the sync work loop and the loop that surrounds the body of the render phase catch block. The async loop could also fall into an infinite loop if the deadline never terminates, but we'll assume that it always eventually does. This change also creates better error stack traces because the error is thrown from inside the first setState that exceeds the limit. Added a test case for an error boundary whose parent remounts it on recovery. * Use invokeGuardedCallback in DEV
Changed paths7 files
First-parent comparisonscripts/fiber/tests-passing.txt ModifiedM src/renderers/__tests__/ReactUpdates-test.js ModifiedM src/renderers/shared/fiber/ReactDebugFiberPerf.js ModifiedM src/renderers/shared/fiber/ReactFiberBeginWork.js ModifiedM src/renderers/shared/fiber/ReactFiberScheduler.js ModifiedM src/renderers/shared/fiber/__tests__/ReactIncrementalTriangle-test.js ModifiedM src/renderers/shared/fiber/__tests__/__snapshots__/ReactIncrementalPerf-test.js.snap ModifiedPatch
Files changed
Rendering syntax-highlighted changes…