diff --git a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js
index cdaaec4b3eeba..1e9ee657e0ca8 100644
--- a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js
+++ b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js
@@ -34,7 +34,6 @@ import {getCurrentRootHostContainer} from 'react-reconciler/src/ReactFiberHostCo
import hasOwnProperty from 'shared/hasOwnProperty';
import {checkAttributeStringCoercion} from 'shared/CheckStringCoercion';
import {REACT_CONTEXT_TYPE} from 'shared/ReactSymbols';
-import {OffscreenComponent} from 'react-reconciler/src/ReactWorkTags';
export {
setCurrentUpdatePriority,
@@ -54,6 +53,8 @@ import {
markNodeAsHoistable,
isOwnedInstance,
} from './ReactDOMComponentTree';
+import {traverseFragmentInstance} from 'react-reconciler/src/ReactFiberTreeReflection';
+
export {detachDeletedInstance};
import {hasRole} from './DOMAccessibilityRoles';
import {
@@ -2221,9 +2222,8 @@ FragmentInstance.prototype.addEventListener = function (
indexOfEventListener(listeners, type, listener, optionsOrUseCapture) === -1;
if (isNewEventListener) {
listeners.push({type, listener, optionsOrUseCapture});
- traverseFragmentInstanceChildren(
- this,
- this._fragmentFiber.child,
+ traverseFragmentInstance(
+ this._fragmentFiber,
addEventListenerToChild,
type,
listener,
@@ -2253,9 +2253,8 @@ FragmentInstance.prototype.removeEventListener = function (
return;
}
if (typeof listeners !== 'undefined' && listeners.length > 0) {
- traverseFragmentInstanceChildren(
- this,
- this._fragmentFiber.child,
+ traverseFragmentInstance(
+ this._fragmentFiber,
removeEventListenerFromChild,
type,
listener,
@@ -2283,45 +2282,9 @@ function removeEventListenerFromChild(
}
// $FlowFixMe[prop-missing]
FragmentInstance.prototype.focus = function (this: FragmentInstanceType) {
- traverseFragmentInstanceChildren(
- this,
- this._fragmentFiber.child,
- setFocusIfFocusable,
- );
+ traverseFragmentInstance(this._fragmentFiber, setFocusIfFocusable);
};
-function traverseFragmentInstanceChildren(
- fragmentInstance: FragmentInstanceType,
- child: Fiber | null,
- fn: (Instance, A, B, C) => boolean,
- a: A,
- b: B,
- c: C,
-): void {
- while (child !== null) {
- if (child.tag === HostComponent) {
- if (fn(child.stateNode, a, b, c)) {
- return;
- }
- } else if (
- child.tag === OffscreenComponent &&
- child.memoizedState !== null
- ) {
- // Skip hidden subtrees
- } else {
- traverseFragmentInstanceChildren(
- fragmentInstance,
- child.child,
- fn,
- a,
- b,
- c,
- );
- }
- child = child.sibling;
- }
-}
-
function normalizeListenerOptions(
opts: ?EventListenerOptionsOrUseCapture,
): string {
diff --git a/packages/react-reconciler/src/ReactFiberTreeReflection.js b/packages/react-reconciler/src/ReactFiberTreeReflection.js
index 5dce60a559fd8..14ce8405d7b99 100644
--- a/packages/react-reconciler/src/ReactFiberTreeReflection.js
+++ b/packages/react-reconciler/src/ReactFiberTreeReflection.js
@@ -8,7 +8,7 @@
*/
import type {Fiber} from './ReactInternalTypes';
-import type {Container, SuspenseInstance} from './ReactFiberConfig';
+import type {Container, SuspenseInstance, Instance} from './ReactFiberConfig';
import type {SuspenseState} from './ReactFiberSuspenseComponent';
import {
@@ -19,6 +19,7 @@ import {
HostPortal,
HostText,
SuspenseComponent,
+ OffscreenComponent,
} from './ReactWorkTags';
import {NoFlags, Placement, Hydrating} from './ReactFiberFlags';
@@ -317,3 +318,37 @@ export function doesFiberContain(
}
return false;
}
+
+export function traverseFragmentInstance(
+ fragmentFiber: Fiber,
+ fn: (Instance, A, B, C) => boolean,
+ a: A,
+ b: B,
+ c: C,
+): void {
+ return traverseFragmentInstanceChildren(fragmentFiber.child, fn, a, b, c);
+}
+
+function traverseFragmentInstanceChildren(
+ child: Fiber | null,
+ fn: (Instance, A, B, C) => boolean,
+ a: A,
+ b: B,
+ c: C,
+): void {
+ while (child !== null) {
+ if (child.tag === HostComponent) {
+ if (fn(child.stateNode, a, b, c)) {
+ return;
+ }
+ } else if (
+ child.tag === OffscreenComponent &&
+ child.memoizedState !== null
+ ) {
+ // Skip hidden subtrees
+ } else {
+ traverseFragmentInstanceChildren(child.child, fn, a, b, c);
+ }
+ child = child.sibling;
+ }
+}