diff --git a/packages/react-dom/src/__tests__/ReactDOMFragmentRefs-test.js b/packages/react-dom/src/__tests__/ReactDOMFragmentRefs-test.js
index 2ac6cb0a4b60..26de45076f35 100644
--- a/packages/react-dom/src/__tests__/ReactDOMFragmentRefs-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMFragmentRefs-test.js
@@ -1613,6 +1613,116 @@ describe('FragmentRefs', () => {
);
});
+ // @gate enableFragmentRefs
+ it('compares a root-level Fragment', async () => {
+ const fragmentRef = React.createRef();
+ const emptyFragmentRef = React.createRef();
+ const childRef = React.createRef();
+ const siblingPrecedingRef = React.createRef();
+ const siblingFollowingRef = React.createRef();
+ const root = ReactDOMClient.createRoot(container);
+
+ function Test() {
+ return (
+
+
+
+
+
+
+
+
+ );
+ }
+
+ await act(() => root.render());
+
+ const fragmentInstance = fragmentRef.current;
+ if (fragmentInstance == null) {
+ throw new Error('Expected fragment instance to be non-null');
+ }
+ const emptyFragmentInstance = emptyFragmentRef.current;
+ if (emptyFragmentInstance == null) {
+ throw new Error('Expected empty fragment instance to be non-null');
+ }
+
+ expectPosition(
+ fragmentInstance.compareDocumentPosition(childRef.current),
+ {
+ preceding: false,
+ following: false,
+ contains: false,
+ containedBy: true,
+ disconnected: false,
+ implementationSpecific: false,
+ },
+ );
+
+ expectPosition(
+ fragmentInstance.compareDocumentPosition(siblingPrecedingRef.current),
+ {
+ preceding: true,
+ following: false,
+ contains: false,
+ containedBy: false,
+ disconnected: false,
+ implementationSpecific: false,
+ },
+ );
+
+ expectPosition(
+ fragmentInstance.compareDocumentPosition(siblingFollowingRef.current),
+ {
+ preceding: false,
+ following: true,
+ contains: false,
+ containedBy: false,
+ disconnected: false,
+ implementationSpecific: false,
+ },
+ );
+
+ expectPosition(
+ emptyFragmentInstance.compareDocumentPosition(childRef.current),
+ {
+ preceding: true,
+ following: false,
+ contains: false,
+ containedBy: false,
+ disconnected: false,
+ implementationSpecific: true,
+ },
+ );
+
+ expectPosition(
+ emptyFragmentInstance.compareDocumentPosition(
+ siblingPrecedingRef.current,
+ ),
+ {
+ preceding: true,
+ following: false,
+ contains: false,
+ containedBy: false,
+ disconnected: false,
+ implementationSpecific: true,
+ },
+ );
+
+ expectPosition(
+ emptyFragmentInstance.compareDocumentPosition(
+ siblingFollowingRef.current,
+ ),
+ {
+ preceding: false,
+ following: true,
+ contains: false,
+ containedBy: false,
+ disconnected: false,
+ implementationSpecific: true,
+ },
+ );
+ });
+
describe('with portals', () => {
// @gate enableFragmentRefs
it('handles portaled elements', async () => {
diff --git a/packages/react-native-renderer/src/ReactFiberConfigFabric.js b/packages/react-native-renderer/src/ReactFiberConfigFabric.js
index 233c267a1d6a..19dd8af1b5ac 100644
--- a/packages/react-native-renderer/src/ReactFiberConfigFabric.js
+++ b/packages/react-native-renderer/src/ReactFiberConfigFabric.js
@@ -25,7 +25,6 @@ import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
import {HostText} from 'react-reconciler/src/ReactWorkTags';
import {
getFragmentParentHostFiber,
- getInstanceFromHostFiber,
traverseFragmentInstance,
} from 'react-reconciler/src/ReactFiberTreeReflection';
@@ -303,6 +302,13 @@ export function getPublicInstance(instance: Instance): null | PublicInstance {
return instance.canonical.publicInstance;
}
+ // Handle root containers
+ if (instance.containerInfo != null) {
+ if (instance.containerInfo.publicInstance != null) {
+ return instance.containerInfo.publicInstance;
+ }
+ }
+
// For compatibility with the legacy renderer, in case it's used with Fabric
// in the same app.
// $FlowExpectedError[prop-missing]
@@ -347,9 +353,8 @@ export function getPublicInstanceFromInternalInstanceHandle(
}
function getPublicInstanceFromHostFiber(fiber: Fiber): PublicInstance {
- const instance = getInstanceFromHostFiber(fiber);
- const publicInstance = getPublicInstance(instance);
- if (publicInstance == null) {
+ const publicInstance = getPublicInstance(fiber.stateNode);
+ if (publicInstance === null) {
throw new Error('Expected to find a host node. This is a bug in React.');
}
return publicInstance;
@@ -691,11 +696,11 @@ FragmentInstance.prototype.compareDocumentPosition = function (
if (parentHostFiber === null) {
return Node.DOCUMENT_POSITION_DISCONNECTED;
}
- const parentHostInstance = getPublicInstanceFromHostFiber(parentHostFiber);
const children: Array = [];
traverseFragmentInstance(this._fragmentFiber, collectChildren, children);
if (children.length === 0) {
- return compareDocumentPositionForEmptyFragment(
+ const parentHostInstance = getPublicInstanceFromHostFiber(parentHostFiber);
+ return compareDocumentPositionForEmptyFragment(
this._fragmentFiber,
parentHostInstance,
otherNode,