dillon1000/react
Commit
Browse files Refactor of interleaved ("concurrent") update queue (#24663)
* Always push updates to interleaved queue first Interleaves updates (updates that are scheduled while another render is already is progress) go into a special queue that isn't applied until the end of the current render. They are transferred to the "real" queue at the beginning of the next render. Currently we check during `setState` whether an update should go directly onto the real queue or onto the special interleaved queue. The logic is subtle and it can lead to bugs if you mess it up, as in #24400. Instead, this changes it to always go onto the interleaved queue. The behavior is the same but the logic is simpler. As a further step, we can also wait to update the `childLanes` until the end of the current render. I'll do this in the next step. * Move setState return path traversal to own call A lot of the logic around scheduling an update needs access to the fiber root. To obtain this reference, we must walk up the fiber return path. We also do this to update `childLanes` on all the parent nodes, so we can use the same traversal for both purposes. The traversal currently happens inside `scheduleUpdateOnFiber`, but sometimes we need to access it beyond that function, too. So I've hoisted the traversal out of `scheduleUpdateOnFiber` into its own function call that happens at the beginning of the `setState` algorithm. * Rename ReactInterleavedUpdates -> ReactFiberConcurrentUpdates The scope of this module is expanding so I've renamed accordingly. No behavioral changes. * Enqueue and update childLanes in same function During a setState, the childLanes are updated immediately, even if a render is already in progress. This can lead to subtle concurrency bugs, so the plan is to wait until the in-progress render has finished before updating the childLanes, to prevent subtle concurrency bugs. As a step toward that change, when scheduling an update, we should not update the childLanes directly, but instead defer to the ReactConcurrentUpdates module to do it at the appropriate time. This makes markUpdateLaneFromFiberToRoot a private function that is only called from the ReactConcurrentUpdates module. * [FORKED] Don't update childLanes until after current render (This is the riskiest commit in the stack. Only affects the "new" reconciler fork.) Updates that occur in a concurrent event while a render is already in progress can't be processed during that render. This is tricky to get right. Previously we solved this by adding concurrent updates to a special `interleaved` queue, then transferring the `interleaved` queue to the `pending` queue after the render phase had completed. However, we would still mutate the `childLanes` along the parent path immediately, which can lead to its own subtle data races. Instead, we can queue the entire operation until after the render phase has completed. This replaces the need for an `interleaved` field on every fiber/hook queue. The main motivation for this change, aside from simplifying the logic a bit, is so we can read information about the current fiber while we're walking up its return path, like whether it's inside a hidden tree. (I haven't done anything like that in this commit, though.) * Add 17691ac to forked revisions
Changed paths28 files
First-parent comparisonpackages/react-noop-renderer/src/createReactNoop.js ModifiedM packages/react-reconciler/src/ReactFiberBeginWork.new.js ModifiedM packages/react-reconciler/src/ReactFiberBeginWork.old.js ModifiedM packages/react-reconciler/src/ReactFiberClassComponent.new.js ModifiedM packages/react-reconciler/src/ReactFiberClassComponent.old.js ModifiedR packages/react-reconciler/src/ReactUpdateQueue.new.js →packages/react-reconciler/src/ReactFiberClassUpdateQueue.new.js RenamedR packages/react-reconciler/src/ReactUpdateQueue.old.js →packages/react-reconciler/src/ReactFiberClassUpdateQueue.old.js RenamedM packages/react-reconciler/src/ReactFiberCommitWork.new.js ModifiedM packages/react-reconciler/src/ReactFiberCommitWork.old.js ModifiedA packages/react-reconciler/src/ReactFiberConcurrentUpdates.new.js AddedA packages/react-reconciler/src/ReactFiberConcurrentUpdates.old.js AddedM packages/react-reconciler/src/ReactFiberHooks.new.js ModifiedM packages/react-reconciler/src/ReactFiberHooks.old.js ModifiedM packages/react-reconciler/src/ReactFiberHotReloading.new.js ModifiedM packages/react-reconciler/src/ReactFiberHotReloading.old.js ModifiedD packages/react-reconciler/src/ReactFiberInterleavedUpdates.new.js DeletedD packages/react-reconciler/src/ReactFiberInterleavedUpdates.old.js DeletedM packages/react-reconciler/src/ReactFiberNewContext.new.js ModifiedM packages/react-reconciler/src/ReactFiberNewContext.old.js ModifiedM packages/react-reconciler/src/ReactFiberReconciler.new.js ModifiedM packages/react-reconciler/src/ReactFiberReconciler.old.js ModifiedM packages/react-reconciler/src/ReactFiberRoot.new.js ModifiedM packages/react-reconciler/src/ReactFiberRoot.old.js ModifiedM packages/react-reconciler/src/ReactFiberThrow.new.js ModifiedM packages/react-reconciler/src/ReactFiberThrow.old.js ModifiedM packages/react-reconciler/src/ReactFiberWorkLoop.new.js ModifiedM packages/react-reconciler/src/ReactFiberWorkLoop.old.js ModifiedM scripts/merge-fork/forked-revisions ModifiedPatch
Files changed
Rendering syntax-highlighted changes…