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; + } +}