@samitouri / QOS-React-2 / commits / 6cff70a740

[react-interactions] Expost host instance to Scope Query function (#17341)

Dominic Gannaway committed Nov 11, 2019 at 13:51 UTC 6cff70a740d1e6ad10070ebf88514bd3a49d0f0d
3 files changed +31 -33
packages/react-reconciler/src/ReactFiberScope.js
+17 -20
@@ -35,17 +35,16 @@ const emptyObject = {};
35
36 function collectScopedNodes(
37 node: Fiber,
38 - fn: (type: string | Object, props: Object) => boolean,
38 + fn: (type: string | Object, props: Object, instance: Object) => boolean,
39 scopedNodes: Array<any>,
40 - searchNode: null | Set<Object>,
40 ): void {
41 if (enableScopeAPI) {
42 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);
45 if (
47 - (searchNode !== null && searchNode.has(instance)) ||
48 - fn(type, memoizedProps || emptyObject) === true
46 + instance !== null &&
47 + fn(type, memoizedProps || emptyObject, instance) === true
48 ) {
49 scopedNodes.push(instance);
50 }
@@ -56,20 +55,21 @@ function collectScopedNodes(
55 child = getSuspenseFallbackChild(node);
56 }
57 if (child !== null) {
59 - collectScopedNodesFromChildren(child, fn, scopedNodes, searchNode);
58 + collectScopedNodesFromChildren(child, fn, scopedNodes);
59 }
60 }
61 }
62
63 function collectFirstScopedNode(
64 node: Fiber,
66 - fn: (type: string | Object, props: Object) => boolean,
65 + fn: (type: string | Object, props: Object, instance: Object) => boolean,
66 ): null | Object {
67 if (enableScopeAPI) {
68 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;
73 }
74 }
75 let child = node.child;
@@ -86,20 +86,19 @@ function collectFirstScopedNode(
86
87 function collectScopedNodesFromChildren(
88 startingChild: Fiber,
89 - fn: (type: string | Object, props: Object) => boolean,
89 + fn: (type: string | Object, props: Object, instance: Object) => boolean,
90 scopedNodes: Array<any>,
91 - searchNode: null | Set<Object>,
91 ): void {
92 let child = startingChild;
93 while (child !== null) {
95 - collectScopedNodes(child, fn, scopedNodes, searchNode);
94 + collectScopedNodes(child, fn, scopedNodes);
95 child = child.sibling;
96 }
97 }
98
99 function collectFirstScopedNodeFromChildren(
100 startingChild: Fiber,
102 - fn: (type: string | Object, props: Object) => boolean,
101 + fn: (type: string | Object, props: Object, instance: Object) => boolean,
102 ): Object | null {
103 let child = startingChild;
104 while (child !== null) {
@@ -197,20 +196,18 @@ export function createScopeMethods(
196 return currentFiber.memoizedProps;
197 },
198 queryAllNodes(
200 - fn: (type: string | Object, props: Object) => boolean,
201 - searchNodes?: Array<Object>,
199 + fn: (type: string | Object, props: Object, instance: Object) => boolean,
200 ): null | Array<Object> {
201 const currentFiber = ((instance.fiber: any): Fiber);
202 const child = currentFiber.child;
203 const scopedNodes = [];
206 - const searchNodeSet = searchNodes ? new Set(searchNodes) : null;
204 if (child !== null) {
208 - collectScopedNodesFromChildren(child, fn, scopedNodes, searchNodeSet);
205 + collectScopedNodesFromChildren(child, fn, scopedNodes);
206 }
207 return scopedNodes.length === 0 ? null : scopedNodes;
208 },
209 queryFirstNode(
213 - fn: (type: string | Object, props: Object) => boolean,
210 + fn: (type: string | Object, props: Object, instance: Object) => boolean,
211 ): null | Object {
212 const currentFiber = ((instance.fiber: any): Fiber);
213 const child = currentFiber.child;
packages/react-reconciler/src/__tests__/ReactScope-test.internal.js
+12 -10
@@ -72,7 +72,7 @@ describe('ReactScope', () => {
72 expect(scopeRef.current).toBe(null);
73 });
74
75 - it('queryAllNodes() works as intended with included nodes array', () => {
75 + it('queryAllNodes() provides the correct host instance', () => {
76 const testScopeQuery = (type, props) => type === 'div';
77 const TestScope = React.unstable_createScope();
78 const scopeRef = React.createRef();
@@ -99,18 +99,20 @@ describe('ReactScope', () => {
99 ReactDOM.render(<Test toggle={true} />, container);
100 let nodes = scopeRef.current.queryAllNodes(testScopeQuery);
101 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);
105 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);
110 expect(nodes).toEqual([divRef.current, spanRef.current, aRef.current]);
111 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);
116 expect(nodes).toEqual([aRef.current, divRef.current, spanRef.current]);
117 ReactDOM.render(null, container);
118 expect(scopeRef.current).toBe(null);
packages/shared/ReactTypes.js
+2 -3
@@ -170,11 +170,10 @@ export type ReactScopeMethods = {|
170 getParent(): null | ReactScopeMethods,
171 getProps(): Object,
172 queryAllNodes(
173 - (type: string | Object, props: Object) => boolean,
174 - searchNodes?: Array<Object>,
173 + (type: string | Object, props: Object, instance: Object) => boolean,
174 ): null | Array<Object>,
175 queryFirstNode(
177 - (type: string | Object, props: Object) => boolean,
176 + (type: string | Object, props: Object, instance: Object) => boolean,
177 ): null | Object,
178 containsNode(Object): boolean,
179 |};