-
Notifications
You must be signed in to change notification settings - Fork 47k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Decouple update queue from Fiber type (#12600)
* Decouple update queue from Fiber type The update queue is in need of a refactor. Recent bugfixes (#12528) have exposed some flaws in how it's modeled. Upcoming features like Suspense and [redacted] also rely on the update queue in ways that weren't anticipated in the original design. Major changes: - Instead of boolean flags for `isReplace` and `isForceUpdate`, updates have a `tag` field (like Fiber). This lowers the cost for adding new types of updates. - Render phase updates are special cased. Updates scheduled during the render phase are dropped if the work-in-progress does not commit. This is used for `getDerivedStateFrom{Props,Catch}`. - `callbackList` has been replaced with a generic effect list. Aside from callbacks, this is also used for `componentDidCatch`. * Remove first class UpdateQueue types and use closures instead I tried to avoid this at first, since we avoid it everywhere else in the Fiber codebase, but since updates are not in a hot path, the trade off with file size seems worth it. * Store captured errors on a separate part of the update queue This way they can be reused independently of updates like getDerivedStateFromProps. This will be important for resuming. * Revert back to storing hasForceUpdate on the update queue Instead of using the effect tag. Ideally, this would be part of the return type of processUpdateQueue. * Rename UpdateQueue effect type back to Callback I don't love this name either, but it's less confusing than UpdateQueue I suppose. Conceptually, this is usually a callback: setState callbacks, componentDidCatch. The only case that feels a bit weird is Timeouts, which use this effect to attach a promise listener. I guess that kinda fits, too. * Call getDerivedStateFromProps every render, even if props did not change Rather than enqueue a new setState updater for every props change, we can skip the update queue entirely and merge the result into state at the end. This makes more sense, since "receiving props" is not an event that should be observed. It's still a bit weird, since eventually we do persist the derived state (in other words, it accumulates). * Store captured effects on separate list from "own" effects (callbacks) For resuming, we need the ability to discard the "own" effects while reusing the captured effects. * Optimize for class components Change `process` and `callback` to match the expected payload types for class components. I had intended for the update queue to be reusable for both class components and a future React API, but we'll likely have to fork anyway. * Only double-invoke render phase lifecycles functions in DEV * Use global state to track currently processing queue in DEV
- Loading branch information
Showing
17 changed files
with
1,112 additions
and
1,005 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.