Skip to content

Commit 6cff70a

Browse files
authored
[react-interactions] Expost host instance to Scope Query function (#17341)
1 parent b8f8258 commit 6cff70a

File tree

3 files changed

+31
-33
lines changed

3 files changed

+31
-33
lines changed

packages/react-reconciler/src/ReactFiberScope.js

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,16 @@ const emptyObject = {};
3535

3636
function collectScopedNodes(
3737
node: Fiber,
38-
fn: (type: string | Object, props: Object) => boolean,
38+
fn: (type: string | Object, props: Object, instance: Object) => boolean,
3939
scopedNodes: Array<any>,
40-
searchNode: null | Set<Object>,
4140
): void {
4241
if (enableScopeAPI) {
4342
if (node.tag === HostComponent) {
44-
const instance = getPublicInstance(node.stateNode);
45-
const {type, memoizedProps} = node;
43+
const {type, memoizedProps, stateNode} = node;
44+
const instance = getPublicInstance(stateNode);
4645
if (
47-
(searchNode !== null && searchNode.has(instance)) ||
48-
fn(type, memoizedProps || emptyObject) === true
46+
instance !== null &&
47+
fn(type, memoizedProps || emptyObject, instance) === true
4948
) {
5049
scopedNodes.push(instance);
5150
}
@@ -56,20 +55,21 @@ function collectScopedNodes(
5655
child = getSuspenseFallbackChild(node);
5756
}
5857
if (child !== null) {
59-
collectScopedNodesFromChildren(child, fn, scopedNodes, searchNode);
58+
collectScopedNodesFromChildren(child, fn, scopedNodes);
6059
}
6160
}
6261
}
6362

6463
function collectFirstScopedNode(
6564
node: Fiber,
66-
fn: (type: string | Object, props: Object) => boolean,
65+
fn: (type: string | Object, props: Object, instance: Object) => boolean,
6766
): null | Object {
6867
if (enableScopeAPI) {
6968
if (node.tag === HostComponent) {
70-
const {type, memoizedProps} = node;
71-
if (fn(type, memoizedProps) === true) {
72-
return getPublicInstance(node.stateNode);
69+
const {type, memoizedProps, stateNode} = node;
70+
const instance = getPublicInstance(stateNode);
71+
if (instance !== null && fn(type, memoizedProps, instance) === true) {
72+
return instance;
7373
}
7474
}
7575
let child = node.child;
@@ -86,20 +86,19 @@ function collectFirstScopedNode(
8686

8787
function collectScopedNodesFromChildren(
8888
startingChild: Fiber,
89-
fn: (type: string | Object, props: Object) => boolean,
89+
fn: (type: string | Object, props: Object, instance: Object) => boolean,
9090
scopedNodes: Array<any>,
91-
searchNode: null | Set<Object>,
9291
): void {
9392
let child = startingChild;
9493
while (child !== null) {
95-
collectScopedNodes(child, fn, scopedNodes, searchNode);
94+
collectScopedNodes(child, fn, scopedNodes);
9695
child = child.sibling;
9796
}
9897
}
9998

10099
function collectFirstScopedNodeFromChildren(
101100
startingChild: Fiber,
102-
fn: (type: string | Object, props: Object) => boolean,
101+
fn: (type: string | Object, props: Object, instance: Object) => boolean,
103102
): Object | null {
104103
let child = startingChild;
105104
while (child !== null) {
@@ -197,20 +196,18 @@ export function createScopeMethods(
197196
return currentFiber.memoizedProps;
198197
},
199198
queryAllNodes(
200-
fn: (type: string | Object, props: Object) => boolean,
201-
searchNodes?: Array<Object>,
199+
fn: (type: string | Object, props: Object, instance: Object) => boolean,
202200
): null | Array<Object> {
203201
const currentFiber = ((instance.fiber: any): Fiber);
204202
const child = currentFiber.child;
205203
const scopedNodes = [];
206-
const searchNodeSet = searchNodes ? new Set(searchNodes) : null;
207204
if (child !== null) {
208-
collectScopedNodesFromChildren(child, fn, scopedNodes, searchNodeSet);
205+
collectScopedNodesFromChildren(child, fn, scopedNodes);
209206
}
210207
return scopedNodes.length === 0 ? null : scopedNodes;
211208
},
212209
queryFirstNode(
213-
fn: (type: string | Object, props: Object) => boolean,
210+
fn: (type: string | Object, props: Object, instance: Object) => boolean,
214211
): null | Object {
215212
const currentFiber = ((instance.fiber: any): Fiber);
216213
const child = currentFiber.child;

packages/react-reconciler/src/__tests__/ReactScope-test.internal.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ describe('ReactScope', () => {
7272
expect(scopeRef.current).toBe(null);
7373
});
7474

75-
it('queryAllNodes() works as intended with included nodes array', () => {
75+
it('queryAllNodes() provides the correct host instance', () => {
7676
const testScopeQuery = (type, props) => type === 'div';
7777
const TestScope = React.unstable_createScope();
7878
const scopeRef = React.createRef();
@@ -99,18 +99,20 @@ describe('ReactScope', () => {
9999
ReactDOM.render(<Test toggle={true} />, container);
100100
let nodes = scopeRef.current.queryAllNodes(testScopeQuery);
101101
expect(nodes).toEqual([divRef.current]);
102-
nodes = scopeRef.current.queryAllNodes(testScopeQuery, [spanRef.current]);
102+
let filterQuery = (type, props, instance) =>
103+
instance === spanRef.current || testScopeQuery(type, props);
104+
nodes = scopeRef.current.queryAllNodes(filterQuery);
103105
expect(nodes).toEqual([divRef.current, spanRef.current]);
104-
nodes = scopeRef.current.queryAllNodes(testScopeQuery, [
105-
spanRef.current,
106-
aRef.current,
107-
]);
106+
filterQuery = (type, props, instance) =>
107+
[spanRef.current, aRef.current].includes(instance) ||
108+
testScopeQuery(type, props);
109+
nodes = scopeRef.current.queryAllNodes(filterQuery);
108110
expect(nodes).toEqual([divRef.current, spanRef.current, aRef.current]);
109111
ReactDOM.render(<Test toggle={false} />, container);
110-
nodes = scopeRef.current.queryAllNodes(testScopeQuery, [
111-
spanRef.current,
112-
aRef.current,
113-
]);
112+
filterQuery = (type, props, instance) =>
113+
[spanRef.current, aRef.current].includes(instance) ||
114+
testScopeQuery(type, props);
115+
nodes = scopeRef.current.queryAllNodes(filterQuery);
114116
expect(nodes).toEqual([aRef.current, divRef.current, spanRef.current]);
115117
ReactDOM.render(null, container);
116118
expect(scopeRef.current).toBe(null);

packages/shared/ReactTypes.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,10 @@ export type ReactScopeMethods = {|
170170
getParent(): null | ReactScopeMethods,
171171
getProps(): Object,
172172
queryAllNodes(
173-
(type: string | Object, props: Object) => boolean,
174-
searchNodes?: Array<Object>,
173+
(type: string | Object, props: Object, instance: Object) => boolean,
175174
): null | Array<Object>,
176175
queryFirstNode(
177-
(type: string | Object, props: Object) => boolean,
176+
(type: string | Object, props: Object, instance: Object) => boolean,
178177
): null | Object,
179178
containsNode(Object): boolean,
180179
|};

0 commit comments

Comments
 (0)