-
Notifications
You must be signed in to change notification settings - Fork 47k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement HostSingleton #25426
Implement HostSingleton #25426
Conversation
Comparing: aa9988e...e8a7aea Critical size changesIncludes critical production bundles, as well as any change greater than 2%:
Significant size changesIncludes any change greater than 0.2%: Expand to show |
@@ -59,6 +59,6 @@ export const disableNativeComponentFrames = false; | |||
export const createRootStrictEffectsByDefault = false; | |||
export const enableStrictEffects = false; | |||
export const allowConcurrentByDefault = true; | |||
export const enableFloat = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You still want to keep the Float flag for the other stuff, right? nvm. That's already hard coded to false in www.
@@ -59,6 +59,6 @@ export const disableNativeComponentFrames = false; | |||
export const createRootStrictEffectsByDefault = false; | |||
export const enableStrictEffects = false; | |||
export const allowConcurrentByDefault = true; | |||
export const enableFloat = false; | |||
export const enableHostSingletons = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need this if it's hardcoded to false below in www.
tag === HostComponent || | ||
tag === HostText || | ||
(enableFloat ? tag === HostResource : false) || | ||
(enableHostSingletons && tag === HostSingleton) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting use of two different stylistic patterns. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this check supportsSingletons
too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was a litmus test to see how closely you reviewed these PRs, you passed!
No actually it was was rebase artifact. I tried the new style to see if CC could figure out how to omit the || !1
when the flag is false but no luck, either form leaves behind these artifacts in the stable prod build. I did it one way originally in HostSingleton, tried the other way in Float, and then missed this on rebase to main
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, re: supportsSingletons
this file gets built without a hostconfig in one entrypoint so I can't import from that file or would need to make a fake entrypoint for it. Presumably it is safe enough to not have the check b/c there should be no fibers with those types so it's a little extra checking if you build with those flags on for a renderer that doesn't support them.
You did mention last time that this file was going to be deprecated at some point. let me know if you think it needs to be resolved
Marking as draft, I'm going to push some updates to hydration |
|
||
export const supportsSingletons = true; | ||
|
||
export function isHostSingletonInstance( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't need to be exported, does it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function is gone now
if (container.nodeType === ELEMENT_NODE) { | ||
// We have refined the container to Element type | ||
const element: Element = (container: any); | ||
switch (element.tagName.toLowerCase()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can assume this is a HTML and not XHTML document and not do the lowercasing. Just compare the upper case. This should be done elsewhere too for Float.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got rid of lowercases
@@ -521,15 +552,15 @@ export function appendChildToContainer( | |||
export function insertBefore( | |||
parentInstance: Instance, | |||
child: Instance | TextInstance, | |||
beforeChild: Instance | TextInstance | SuspenseInstance, | |||
beforeChild: InstanceSibling, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this new type needed for? It doesn't seem like you're exporting a new type so where is the input coming from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
): boolean { | ||
if (instance.nodeType === ELEMENT_NODE) { | ||
const element: Element = (instance: any); | ||
return isHostSingletonType(element.tagName.toLowerCase()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that because of this second usage, this function doesn't get inlined into the reconciler. We shouldn't use this again here. In fact, we probably shouldn't even have this isHostSingletonInstance
file. Just inline all of it into getNextHydratable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rewrote and eliminated this function
return fiber.tag === HostComponent && fiber.memoizedProps.hidden === true; | ||
return ( | ||
(fiber.tag === HostComponent || | ||
(enableHostSingletons ? fiber.tag === HostSingleton : false)) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feature is going to be removed but it doesn't really make sense for HostSingletons anyway so you can skip this case.
if (!htmlElement) { | ||
htmlElement = ownerDocument.appendChild( | ||
ownerDocument.createElement('html'), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason we shouldn't assume these exists and just error if they don't?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed for errors
function updateHostSingleton( | ||
current: Fiber | null, | ||
workInProgress: Fiber, | ||
renderLanes: Lanes, | ||
) { | ||
pushHostContext(workInProgress); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the complete work phase HostSingletons hit the HostComponent path on update renders. I was going to try to do something similar here but the interaction between single text children and the placement of child fibers beneath is wonky. For now I'll leave it like this which may actually be desirable
(!enableHostSingletons || tag !== 'body') && | ||
(tag !== 'textarea' || nextProp !== ''); | ||
if (canSetTextContent) { | ||
setTextContent(domElement, nextProp); | ||
} | ||
} else if (typeof nextProp === 'number') { | ||
setTextContent(domElement, '' + nextProp); | ||
const canSetTextContent = !enableHostSingletons || tag !== 'body'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, I'm not sure this is the best way to handle the situation with single-child-as-text but what's going on here is
- HostSingletons in beginWork never opt for single-child-as-text so they will always have a child fiber.
- When a singleton is acquired on mount we call setInitialProperties which assumes that if there is a single-child-as-text there won't be a child fiber.
- This is a subtle leak of internals into the host config but the body exclusion is because this is the only singleton that realistically can have a single-child-as-text and we don't want to set the text content here otherwise we'll end up with two copies (once for this insert, and once when the child fiber appends)
as an alternative I could always resetTextContent in the reconciler since the reconciler knows that there should never be this shortcut
OR I could support single-child-as-text for singletons
@@ -983,7 +983,6 @@ describe('ReactDOMFizzServer', () => { | |||
}); | |||
|
|||
// @gate enableSuspenseList | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left over?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I guess, but shouldn't we get rid of the extra line? seems like the gate comment is usually just above the test
Summary: - **[9fb581c7c](facebook/react@9fb581c7c )**: Refactor: merge duplicate imports ([#25489](facebook/react#25489)) //<c0dedance>// - **[bc358362a](facebook/react@bc358362a )**: [Flight] Improve Error Messages when Invalid Object is Passed to Client/Host Components ([#25492](facebook/react#25492)) //<Sebastian Markbåge>// - **[780eacd40](facebook/react@780eacd40 )**: Flow upgrade to 0.190 ([#25483](facebook/react#25483)) //<Jan Kassens>// - **[54f0e0f73](facebook/react@54f0e0f73 )**: Scaffolding for react-dom/unstable_external-server-runtime ([#25482](facebook/react#25482)) //<Andrew Clark>// - **[0eaca3756](facebook/react@0eaca3756 )**: Add script to generate inline Fizz runtime ([#25481](facebook/react#25481)) //<Andrew Clark>// - **[69c7246d9](facebook/react@69c7246d9 )**: Initialize useMemoCache with sentinel values ([#25465](facebook/react#25465)) //<Joseph Savona>// - **[3b814327e](facebook/react@3b814327e )**: Allow Async Functions to be used in Server Components ([#25479](facebook/react#25479)) //<Sebastian Markbåge>// - **[a6bf46689](facebook/react@a6bf46689 )**: Extract Fizz instruction set to build macro ([#25457](facebook/react#25457)) //<Andrew Clark>// - **[ea5bc6bac](facebook/react@ea5bc6bac )**: [React Native FB] dynamic feature flag for ref access warning ([#25471](facebook/react#25471)) //<Jan Kassens>// - **[08d035bc8](facebook/react@08d035bc8 )**: Remove Shallow Renderer Tests ([#25475](facebook/react#25475)) //<Sebastian Markbåge>// - **[a8c16a004](facebook/react@a8c16a004 )**: Split Cache into its own Dispatcher ([#25474](facebook/react#25474)) //<Sebastian Markbåge>// - **[2cf4352e1](facebook/react@2cf4352e1 )**: Implement HostSingleton Fiber type ([#25426](facebook/react#25426)) //<Josh Story>// - **[aa9988e5e](facebook/react@aa9988e5e )**: Server render fork for react-dom ([#25436](facebook/react#25436)) //<Josh Story>// - **[513417d69](facebook/react@513417d69 )**: Return lastNonHostInstance in getInspectorDataForInstance for devtools ([#25441](facebook/react#25441)) //<Tianyu Yao>// - **[5d60a0b84](facebook/react@5d60a0b84 )**: Bugfix: LegacyHidden shouldn't defer effects ([#25442](facebook/react#25442)) //<Andrew Clark>// - **[618388bc3](facebook/react@618388bc3 )**: [Float] Support script preloads ([#25432](facebook/react#25432)) //<Josh Story>// - **[2872a26e1](facebook/react@2872a26e1 )**: track resources in different roots separately ([#25388](facebook/react#25388)) //<Josh Story>// - **[ea04a486a](facebook/react@ea04a486a )**: Flow: remove unused suppressions ([#25424](facebook/react#25424)) //<Jan Kassens>// - **[9813edef2](facebook/react@9813edef2 )**: Flow upgrade to 0.188 //<Jan Kassens>// - **[3b6826ed9](facebook/react@3b6826ed9 )**: Flow: inference_mode=constrain_writes //<Jan Kassens>// - **[aed33a49c](facebook/react@aed33a49c )**: Flow upgrade to 0.185 //<Jan Kassens>// - **[f02a5f5c7](facebook/react@f02a5f5c7 )**: Flow upgrade to 0.182 //<Jan Kassens>// - **[72593f008](facebook/react@72593f008 )**: Flow upgrade to 0.176 //<Jan Kassens>// - **[46d40f306](facebook/react@46d40f306 )**: Flow upgrade to 0.175 //<Jan Kassens>// - **[1089faf0d](facebook/react@1089faf0d )**: Flow: run codemod to remove existential type //<Jan Kassens>// - **[3fd9bd8e7](facebook/react@3fd9bd8e7 )**: Add RulesOfHooks support for `use` //<Lauren Tan>// - **[338e6a967](facebook/react@338e6a967 )**: Flow upgrade to 0.155 //<Jan Kassens>// - **[8bc95bb3c](facebook/react@8bc95bb3c )**: Flow upgrade to 0.154 //<Jan Kassens>// - **[9f8a98a39](facebook/react@9f8a98a39 )**: Flow upgrade to 0.153 //<Jan Kassens>// - **[64fe791be](facebook/react@64fe791be )**: Flow upgrade to 0.146 //<Jan Kassens>// - **[d3c6c16a0](facebook/react@d3c6c16a0 )**: Flow upgrade to 0.145 //<Jan Kassens>// - **[00a2f8150](facebook/react@00a2f8150 )**: Flow upgrade to 0.143 //<Jan Kassens>// - **[0a3072278](facebook/react@0a3072278 )**: Flow: complete types first migration ([#25389](facebook/react#25389)) //<Jan Kassens>// - **[bcc05671f](facebook/react@bcc05671f )**: Flow: types first in shared ([#25343](facebook/react#25343)) //<Jan Kassens>// - **[b1f34aa30](facebook/react@b1f34aa30 )**: Flow: types first in react-native-renderer ([#25363](facebook/react#25363)) //<Jan Kassens>// - **[9143864ae](facebook/react@9143864ae )**: Flow: well formed exports for smaller packages ([#25361](facebook/react#25361)) //<Jan Kassens>// - **[21a851e03](facebook/react@21a851e03 )**: Fix devtools typos and grammar ([#24587](facebook/react#24587)) //<Alexandru Tasica>// - **[cfafeb685](facebook/react@cfafeb685 )**: Remove extra space in Wedge.js ([#24611](facebook/react#24611)) //<Kerim Büyükakyüz>// - **[9c3de25e1](facebook/react@9c3de25e1 )**: Flow: types first in reconciler ([#25362](facebook/react#25362)) //<Jan Kassens>// - **[7b25b961d](facebook/react@7b25b961d )**: [Fizz/Float] Float for stylesheet resources ([#25243](facebook/react#25243)) //<Josh Story>// - **[4c016e7aa](facebook/react@4c016e7aa )**: Refactor: use property shorthand ([#25366](facebook/react#25366)) //<zhangrenyang>// - **[06066c1a5](facebook/react@06066c1a5 )**: Make RulesOfHooks-test more consistent with ExhaustiveDeps-test //<Lauren Tan>// - **[49ae0fad8](facebook/react@49ae0fad8 )**: Fix RulesOfHooks test case indentation //<Lauren Tan>// - **[abbbdf4ce](facebook/react@abbbdf4ce )**: Put modern StrictMode behind a feature flag ([#25365](facebook/react#25365)) //<Samuel Susla>// - **[434110390](facebook/react@434110390 )**: ReactHooks.js - delete emptyObject ([#25031](facebook/react#25031)) //<Igor Berlenko>// - **[31400ce29](facebook/react@31400ce29 )**: Refactor: merge duplicate imports ([#25364](facebook/react#25364)) //<jerry-lllman>// - **[3517bd9f7](facebook/react@3517bd9f7 )**: Refactor useEvent ([#25336](facebook/react#25336)) //<Lauren Tan>// - **[6cf06a929](facebook/react@6cf06a929 )**: Remove outdated comments. ([#24464](facebook/react#24464)) //<zhangenming>// - **[20a257c25](facebook/react@20a257c25 )**: Refactor: more word doubles removed ([#25352](facebook/react#25352)) //<Vic Graf>// - **[8cadcffd5](facebook/react@8cadcffd5 )**: Fix typo: reconcilation -> reconciliation ([#25355](facebook/react#25355)) //<zhangrenyang>// - **[ebbe599a2](facebook/react@ebbe599a2 )**: Fix EventListener fork ([#25347](facebook/react#25347)) //<Sebastian Markbåge>// - **[97d75c9c8](facebook/react@97d75c9c8 )**: Move react-dom implementation files to react-dom-bindings ([#25345](facebook/react#25345)) //<Sebastian Markbåge>// - **[3de926449](facebook/react@3de926449 )**: [Fizz] experimental_useEvent ([#25325](facebook/react#25325)) //<dan>// - **[5b59dd640](facebook/react@5b59dd640 )**: Fix duplicate words tests ([#25333](facebook/react#25333)) //<Vic Graf>// - **[cb5084d1c](facebook/react@cb5084d1c )**: [ESLint] Check useEvent references instead ([#25319](facebook/react#25319)) //<Lauren Tan>// - **[c89a83695](facebook/react@c89a83695 )**: Update RulesOfHooks with useEvent rules ([#25285](facebook/react#25285)) //<Lauren Tan>// - **[efc6a08e9](facebook/react@efc6a08e9 )**: [Flight] Implement error digests for Flight runtime and expose errorInfo in getDerivedStateFromError ([#25302](facebook/react#25302)) //<Josh Story>// - **[c1d414d75](facebook/react@c1d414d75 )**: Add ref to Offscreen component ([#25254](facebook/react#25254)) //<Samuel Susla>// - **[135e33c95](facebook/react@135e33c95 )**: Flow: typing of Scheduler ([#25317](facebook/react#25317)) //<Jan Kassens>// - **[cc8cb145f](facebook/react@cc8cb145f )**: Flow: add some missing types in react-reconciler ([#25316](facebook/react#25316)) //<Jan Kassens>// - **[112d0498c](facebook/react@112d0498c )**: [Fizz] Move digest from errorInfo to Error instance ([#25313](facebook/react#25313)) //<Josh Story>// - **[d1bb1c586](facebook/react@d1bb1c586 )**: Fix memory leak after repeated setState bailouts ([#25309](facebook/react#25309)) //<Andrew Clark>// Changelog: [General][Changed] - React Native sync for revisions 0cac4d5...9fb581c jest_e2e[run_all_tests] Reviewed By: yungsters Differential Revision: D40383219 fbshipit-source-id: dc2a44bd05df041e0c7f2e1060640b1d2c372187
## Summary This is to support two new reconciler work tags `HostSingleton` and `HostResource` introduced in PRs #25243 #25426. The behavior is described below. I also renamed an option in components settings from an internal concept "host" to more understood "dom nodes" ## How did you test this change? Tested on the latest Vercel playground app https://github.com/vercel/app-playground/ Before the change, devtools cannot show correct display name for these new elements. Also, some unnecessary internal details are exposed to users. <img width="1395" alt="image" src="https://user-images.githubusercontent.com/1001890/199578181-c4e4ea74-baa1-4507-83d0-91a62ad7de5f.png"> After the change, the display names are correctly shown and the "state" would always be hidden in the detail view. <img width="1417" alt="image" src="https://user-images.githubusercontent.com/1001890/199578442-adc1951d-7d5b-4b84-ad64-85bcf7a8ebcc.png"> These elements will also be hidden just like other native dom elements (e.g. `<div>`) <img width="836" alt="image" src="https://user-images.githubusercontent.com/1001890/199578598-2dfacf64-ddc9-42b5-a246-dd0b09f629af.png">
## Summary This is to support two new reconciler work tags `HostSingleton` and `HostResource` introduced in PRs facebook#25243 facebook#25426. The behavior is described below. I also renamed an option in components settings from an internal concept "host" to more understood "dom nodes" ## How did you test this change? Tested on the latest Vercel playground app https://github.com/vercel/app-playground/ Before the change, devtools cannot show correct display name for these new elements. Also, some unnecessary internal details are exposed to users. <img width="1395" alt="image" src="https://user-images.githubusercontent.com/1001890/199578181-c4e4ea74-baa1-4507-83d0-91a62ad7de5f.png"> After the change, the display names are correctly shown and the "state" would always be hidden in the detail view. <img width="1417" alt="image" src="https://user-images.githubusercontent.com/1001890/199578442-adc1951d-7d5b-4b84-ad64-85bcf7a8ebcc.png"> These elements will also be hidden just like other native dom elements (e.g. `<div>`) <img width="836" alt="image" src="https://user-images.githubusercontent.com/1001890/199578598-2dfacf64-ddc9-42b5-a246-dd0b09f629af.png">
## Summary This is to support two new reconciler work tags `HostSingleton` and `HostResource` introduced in PRs #25243 #25426. The behavior is described below. I also renamed an option in components settings from an internal concept "host" to more understood "dom nodes" ## How did you test this change? Tested on the latest Vercel playground app https://github.com/vercel/app-playground/ Before the change, devtools cannot show correct display name for these new elements. Also, some unnecessary internal details are exposed to users. <img width="1395" alt="image" src="https://user-images.githubusercontent.com/1001890/199578181-c4e4ea74-baa1-4507-83d0-91a62ad7de5f.png"> After the change, the display names are correctly shown and the "state" would always be hidden in the detail view. <img width="1417" alt="image" src="https://user-images.githubusercontent.com/1001890/199578442-adc1951d-7d5b-4b84-ad64-85bcf7a8ebcc.png"> These elements will also be hidden just like other native dom elements (e.g. `<div>`) <img width="836" alt="image" src="https://user-images.githubusercontent.com/1001890/199578598-2dfacf64-ddc9-42b5-a246-dd0b09f629af.png">
Summary: - **[9fb581c7c](facebook/react@9fb581c7c )**: Refactor: merge duplicate imports ([facebook#25489](facebook/react#25489)) //<c0dedance>// - **[bc358362a](facebook/react@bc358362a )**: [Flight] Improve Error Messages when Invalid Object is Passed to Client/Host Components ([facebook#25492](facebook/react#25492)) //<Sebastian Markbåge>// - **[780eacd40](facebook/react@780eacd40 )**: Flow upgrade to 0.190 ([facebook#25483](facebook/react#25483)) //<Jan Kassens>// - **[54f0e0f73](facebook/react@54f0e0f73 )**: Scaffolding for react-dom/unstable_external-server-runtime ([facebook#25482](facebook/react#25482)) //<Andrew Clark>// - **[0eaca3756](facebook/react@0eaca3756 )**: Add script to generate inline Fizz runtime ([facebook#25481](facebook/react#25481)) //<Andrew Clark>// - **[69c7246d9](facebook/react@69c7246d9 )**: Initialize useMemoCache with sentinel values ([facebook#25465](facebook/react#25465)) //<Joseph Savona>// - **[3b814327e](facebook/react@3b814327e )**: Allow Async Functions to be used in Server Components ([facebook#25479](facebook/react#25479)) //<Sebastian Markbåge>// - **[a6bf46689](facebook/react@a6bf46689 )**: Extract Fizz instruction set to build macro ([facebook#25457](facebook/react#25457)) //<Andrew Clark>// - **[ea5bc6bac](facebook/react@ea5bc6bac )**: [React Native FB] dynamic feature flag for ref access warning ([facebook#25471](facebook/react#25471)) //<Jan Kassens>// - **[08d035bc8](facebook/react@08d035bc8 )**: Remove Shallow Renderer Tests ([facebook#25475](facebook/react#25475)) //<Sebastian Markbåge>// - **[a8c16a004](facebook/react@a8c16a004 )**: Split Cache into its own Dispatcher ([facebook#25474](facebook/react#25474)) //<Sebastian Markbåge>// - **[2cf4352e1](facebook/react@2cf4352e1 )**: Implement HostSingleton Fiber type ([facebook#25426](facebook/react#25426)) //<Josh Story>// - **[aa9988e5e](facebook/react@aa9988e5e )**: Server render fork for react-dom ([facebook#25436](facebook/react#25436)) //<Josh Story>// - **[513417d69](facebook/react@513417d69 )**: Return lastNonHostInstance in getInspectorDataForInstance for devtools ([facebook#25441](facebook/react#25441)) //<Tianyu Yao>// - **[5d60a0b84](facebook/react@5d60a0b84 )**: Bugfix: LegacyHidden shouldn't defer effects ([facebook#25442](facebook/react#25442)) //<Andrew Clark>// - **[618388bc3](facebook/react@618388bc3 )**: [Float] Support script preloads ([facebook#25432](facebook/react#25432)) //<Josh Story>// - **[2872a26e1](facebook/react@2872a26e1 )**: track resources in different roots separately ([facebook#25388](facebook/react#25388)) //<Josh Story>// - **[ea04a486a](facebook/react@ea04a486a )**: Flow: remove unused suppressions ([facebook#25424](facebook/react#25424)) //<Jan Kassens>// - **[9813edef2](facebook/react@9813edef2 )**: Flow upgrade to 0.188 //<Jan Kassens>// - **[3b6826ed9](facebook/react@3b6826ed9 )**: Flow: inference_mode=constrain_writes //<Jan Kassens>// - **[aed33a49c](facebook/react@aed33a49c )**: Flow upgrade to 0.185 //<Jan Kassens>// - **[f02a5f5c7](facebook/react@f02a5f5c7 )**: Flow upgrade to 0.182 //<Jan Kassens>// - **[72593f008](facebook/react@72593f008 )**: Flow upgrade to 0.176 //<Jan Kassens>// - **[46d40f306](facebook/react@46d40f306 )**: Flow upgrade to 0.175 //<Jan Kassens>// - **[1089faf0d](facebook/react@1089faf0d )**: Flow: run codemod to remove existential type //<Jan Kassens>// - **[3fd9bd8e7](facebook/react@3fd9bd8e7 )**: Add RulesOfHooks support for `use` //<Lauren Tan>// - **[338e6a967](facebook/react@338e6a967 )**: Flow upgrade to 0.155 //<Jan Kassens>// - **[8bc95bb3c](facebook/react@8bc95bb3c )**: Flow upgrade to 0.154 //<Jan Kassens>// - **[9f8a98a39](facebook/react@9f8a98a39 )**: Flow upgrade to 0.153 //<Jan Kassens>// - **[64fe791be](facebook/react@64fe791be )**: Flow upgrade to 0.146 //<Jan Kassens>// - **[d3c6c16a0](facebook/react@d3c6c16a0 )**: Flow upgrade to 0.145 //<Jan Kassens>// - **[00a2f8150](facebook/react@00a2f8150 )**: Flow upgrade to 0.143 //<Jan Kassens>// - **[0a3072278](facebook/react@0a3072278 )**: Flow: complete types first migration ([facebook#25389](facebook/react#25389)) //<Jan Kassens>// - **[bcc05671f](facebook/react@bcc05671f )**: Flow: types first in shared ([facebook#25343](facebook/react#25343)) //<Jan Kassens>// - **[b1f34aa30](facebook/react@b1f34aa30 )**: Flow: types first in react-native-renderer ([facebook#25363](facebook/react#25363)) //<Jan Kassens>// - **[9143864ae](facebook/react@9143864ae )**: Flow: well formed exports for smaller packages ([facebook#25361](facebook/react#25361)) //<Jan Kassens>// - **[21a851e03](facebook/react@21a851e03 )**: Fix devtools typos and grammar ([facebook#24587](facebook/react#24587)) //<Alexandru Tasica>// - **[cfafeb685](facebook/react@cfafeb685 )**: Remove extra space in Wedge.js ([facebook#24611](facebook/react#24611)) //<Kerim Büyükakyüz>// - **[9c3de25e1](facebook/react@9c3de25e1 )**: Flow: types first in reconciler ([facebook#25362](facebook/react#25362)) //<Jan Kassens>// - **[7b25b961d](facebook/react@7b25b961d )**: [Fizz/Float] Float for stylesheet resources ([facebook#25243](facebook/react#25243)) //<Josh Story>// - **[4c016e7aa](facebook/react@4c016e7aa )**: Refactor: use property shorthand ([facebook#25366](facebook/react#25366)) //<zhangrenyang>// - **[06066c1a5](facebook/react@06066c1a5 )**: Make RulesOfHooks-test more consistent with ExhaustiveDeps-test //<Lauren Tan>// - **[49ae0fad8](facebook/react@49ae0fad8 )**: Fix RulesOfHooks test case indentation //<Lauren Tan>// - **[abbbdf4ce](facebook/react@abbbdf4ce )**: Put modern StrictMode behind a feature flag ([facebook#25365](facebook/react#25365)) //<Samuel Susla>// - **[434110390](facebook/react@434110390 )**: ReactHooks.js - delete emptyObject ([facebook#25031](facebook/react#25031)) //<Igor Berlenko>// - **[31400ce29](facebook/react@31400ce29 )**: Refactor: merge duplicate imports ([facebook#25364](facebook/react#25364)) //<jerry-lllman>// - **[3517bd9f7](facebook/react@3517bd9f7 )**: Refactor useEvent ([facebook#25336](facebook/react#25336)) //<Lauren Tan>// - **[6cf06a929](facebook/react@6cf06a929 )**: Remove outdated comments. ([facebook#24464](facebook/react#24464)) //<zhangenming>// - **[20a257c25](facebook/react@20a257c25 )**: Refactor: more word doubles removed ([facebook#25352](facebook/react#25352)) //<Vic Graf>// - **[8cadcffd5](facebook/react@8cadcffd5 )**: Fix typo: reconcilation -> reconciliation ([facebook#25355](facebook/react#25355)) //<zhangrenyang>// - **[ebbe599a2](facebook/react@ebbe599a2 )**: Fix EventListener fork ([facebook#25347](facebook/react#25347)) //<Sebastian Markbåge>// - **[97d75c9c8](facebook/react@97d75c9c8 )**: Move react-dom implementation files to react-dom-bindings ([facebook#25345](facebook/react#25345)) //<Sebastian Markbåge>// - **[3de926449](facebook/react@3de926449 )**: [Fizz] experimental_useEvent ([facebook#25325](facebook/react#25325)) //<dan>// - **[5b59dd640](facebook/react@5b59dd640 )**: Fix duplicate words tests ([facebook#25333](facebook/react#25333)) //<Vic Graf>// - **[cb5084d1c](facebook/react@cb5084d1c )**: [ESLint] Check useEvent references instead ([facebook#25319](facebook/react#25319)) //<Lauren Tan>// - **[c89a83695](facebook/react@c89a83695 )**: Update RulesOfHooks with useEvent rules ([facebook#25285](facebook/react#25285)) //<Lauren Tan>// - **[efc6a08e9](facebook/react@efc6a08e9 )**: [Flight] Implement error digests for Flight runtime and expose errorInfo in getDerivedStateFromError ([facebook#25302](facebook/react#25302)) //<Josh Story>// - **[c1d414d75](facebook/react@c1d414d75 )**: Add ref to Offscreen component ([facebook#25254](facebook/react#25254)) //<Samuel Susla>// - **[135e33c95](facebook/react@135e33c95 )**: Flow: typing of Scheduler ([facebook#25317](facebook/react#25317)) //<Jan Kassens>// - **[cc8cb145f](facebook/react@cc8cb145f )**: Flow: add some missing types in react-reconciler ([facebook#25316](facebook/react#25316)) //<Jan Kassens>// - **[112d0498c](facebook/react@112d0498c )**: [Fizz] Move digest from errorInfo to Error instance ([facebook#25313](facebook/react#25313)) //<Josh Story>// - **[d1bb1c586](facebook/react@d1bb1c586 )**: Fix memory leak after repeated setState bailouts ([facebook#25309](facebook/react#25309)) //<Andrew Clark>// Changelog: [General][Changed] - React Native sync for revisions 0cac4d5...9fb581c jest_e2e[run_all_tests] Reviewed By: yungsters Differential Revision: D40383219 fbshipit-source-id: dc2a44bd05df041e0c7f2e1060640b1d2c372187
Background
For a variety of reasons
html
,head
, andbody
nodes are special in the browser and historically there has not been much heed given to these elements in particular within react-dom which has led to some limitations of interoperability with externals systems such as 3rd party scripts and browser extensions. Additionally new features in React will require some special handling of these instances to be possible.The main issue has to do with instance lifecycles and React's total ownership of the nodes within it's tree. For the
head
for instance, if there are stylesheet links inserted by 3rd parties, React might unmount those nodes, or reinsert them somewhere else causing a new fetch and temporary style unloading. Additionally useInsertionEffect runs in the mutation phase but if we are going to be replacing the head it will be unmounted during the time these effects are run so you can't always inject styles when you expected to be able to.The historical advice has been to render into an element in the body that isn't like to be targeted by any external systems however this conflicts with the guidance for using streaming rendering available in React 18 where it is going to be common that React owns the entire document.
General Approach
To solve these issues, this PR introduces a new fiber type
HostSingleton
. Currently only react-dom has an implementation for this type and all other renderers still only useHostComponent
.HostSingletons
are placed individually, they will not be appended to a parent fiber even if they are part of a tree that is going to be Placed in the same commit.HostSingletons
do not append anyHostComponent
childrenHostSingletons
if a Placement effect is needed a special Singleton placement method from the HostConfig is used. Child fibers of the fiber are then appended.HostSingleton
is having Placement effects appended to it, it will use optional additional semantics for finding an insertion edge. This allows for non-react-controlled children to be siblings of Placed fibers without incorrect ordering.react-dom Approach
In the case of react-dom there are three singleton instances,
document.documentElement
,document.head
,document.body
. If you render a<html /> | <head /> | <body />
in your tree they each will bind to the already existing Element and not recreate a new one.Key Constraints: