Skip to content

Commit 132204a

Browse files
committed
Support Promise as a renderable node (#25634)
Implements Promise as a valid React node types. The idea is that any type that can be unwrapped with `use` should also be renderable. When the reconciler encounters a Usable in a child position, it will transparently unwrap the value before reconciling it. The value of the inner value will determine the identity of the child during reconciliation, not the Usable object that wraps around it. Unlike `use`, the reconciler will recursively unwrap the value until it reaches a non-Usable type, e.g. `Usable<Usable<Usable<T>>>` will resolve to T. In this initial commit, I've added support for Promises. I will do Context in the [next step](#25641). Being able to render a promise as a child has several interesting implications. The Server Components response format can use this feature in its implementation — instead of wrapping references to client components in `React.lazy`, it can just use a promise. This also fulfills one of the requirements for async components on the client, because an async component always returns a promise for a React node. However, we will likely warn and/or lint against this for the time being because there are major caveats if you re-render an async component in response to user input. (Note: async components already work in a Server Components environment — the caveats only apply to running them in the browser.) To suspend, React uses the same algorithm as `use`: by throwing an exception to unwind the stack, then replaying the begin phase once the promise resolves. It's a little weird to suspend during reconciliation, however, `lazy` already does this so if there were any obvious bugs related to that we likely would have already found them. Still, the structure is a bit unfortunate. Ideally, we shouldn't need to replay the entire begin phase of the parent fiber in order to reconcile the children again. This would require a somewhat significant refactor, because reconciliation happens deep within the begin phase, and depending on the type of work, not always at the end. We should consider as a future improvement. DiffTrain build for [d4f58c3](d4f58c3)
1 parent 1dd9e4e commit 132204a

25 files changed

+3225
-1957
lines changed

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
93c10dfa6b0848c12189b773b59c77d74cad2a1a
1+
d4f58c3b8123f1654ca1b06692c3165928bef8df

compiled/facebook-www/React-dev.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ if (
2727
}
2828
"use strict";
2929

30-
var ReactVersion = "18.3.0-www-modern-f87ae691";
30+
var ReactVersion = "18.3.0-www-modern-abf2779e";
3131

3232
// ATTENTION
3333
// When adding new symbols to this file,

0 commit comments

Comments
 (0)