@samitouri / QOS-React-2 / commits / 29534252ad

ReactDOM.useEvent add flag and entry point (#18267)

Dominic Gannaway committed Mar 10, 2020 at 12:18 UTC 29534252add3b90f7984a0f1c89937ed32d36ceb
12 files changed +122
packages/react-dom/src/client/ReactDOM.js
+3
@@ -20,6 +20,7 @@ import {
20 unmountComponentAtNode,
21 } from './ReactDOMLegacy';
22 import {createRoot, createBlockingRoot, isValidContainer} from './ReactDOMRoot';
23 +import {useEvent} from './ReactDOMUseEvent';
24
25 import {
26 batchedEventUpdates,
@@ -218,6 +219,8 @@ export {
219 // Temporary alias since we already shipped React 16 RC with it.
220 // TODO: remove in React 17.
221 unstable_createPortal,
222 + // enableUseEventAPI
223 + useEvent as unstable_useEvent,
224 };
225
226 const foundDevTools = injectIntoDevTools({
packages/react-dom/src/client/ReactDOMUseEvent.js new
+74
@@ -0,0 +1,74 @@
1 +/**
2 + * Copyright (c) Facebook, Inc. and its affiliates.
3 + *
4 + * This source code is licensed under the MIT license found in the
5 + * LICENSE file in the root directory of this source tree.
6 + *
7 + * @flow
8 + */
9 +
10 +import type {EventPriority} from 'shared/ReactTypes';
11 +import type {
12 + ReactDOMListenerEvent,
13 + ReactDOMListenerMap,
14 +} from 'shared/ReactDOMTypes';
15 +
16 +import ReactSharedInternals from 'shared/ReactSharedInternals';
17 +import invariant from 'shared/invariant';
18 +
19 +import {getEventPriorityForListenerSystem} from '../events/DOMEventProperties';
20 +
21 +type EventOptions = {|
22 + capture?: boolean,
23 + passive?: boolean,
24 + priority?: EventPriority,
25 +|};
26 +
27 +const {ReactCurrentDispatcher} = ReactSharedInternals;
28 +
29 +function resolveDispatcher() {
30 + const dispatcher = ReactCurrentDispatcher.current;
31 + invariant(
32 + dispatcher !== null,
33 + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
34 + ' one of the following reasons:\n' +
35 + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
36 + '2. You might be breaking the Rules of Hooks\n' +
37 + '3. You might have more than one copy of React in the same app\n' +
38 + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
39 + );
40 + return dispatcher;
41 +}
42 +
43 +export function useEvent(
44 + type: string,
45 + options?: EventOptions,
46 +): ReactDOMListenerMap {
47 + const dispatcher = resolveDispatcher();
48 + let capture = false;
49 + let passive = false;
50 + let priority = getEventPriorityForListenerSystem((type: any));
51 +
52 + if (options != null) {
53 + const optionsCapture = options.capture;
54 + const optionsPassive = options.passive;
55 + const optionsPriority = options.priority;
56 +
57 + if (typeof optionsCapture === 'boolean') {
58 + capture = optionsCapture;
59 + }
60 + if (typeof optionsPassive === 'boolean') {
61 + passive = optionsPassive;
62 + }
63 + if (typeof optionsPriority === 'number') {
64 + priority = optionsPriority;
65 + }
66 + }
67 + const event: ReactDOMListenerEvent = {
68 + capture,
69 + passive,
70 + priority,
71 + type,
72 + };
73 + return dispatcher.useEvent(event);
74 +}
packages/react-dom/src/events/DOMEventProperties.js
+14
@@ -223,3 +223,17 @@ export function getEventPriorityForPluginSystem(
223 // for the event.
224 return priority === undefined ? ContinuousEvent : priority;
225 }
226 +
227 +export function getEventPriorityForListenerSystem(type: string): EventPriority {
228 + const priority = eventPriorities.get(((type: any): TopLevelType));
229 + if (priority !== undefined) {
230 + return priority;
231 + }
232 + if (__DEV__) {
233 + console.warn(
234 + 'The event "type" provided to useEvent() does not have a known priority type.' +
235 + ' It is recommended to provide a "priority" option to specify a priority.',
236 + );
237 + }
238 + return ContinuousEvent;
239 +}
packages/shared/ReactDOMTypes.js
+20
@@ -75,3 +75,23 @@ export type ReactDOMResponderContext = {
75 getResponderNode(): Element | null,
76 ...
77 };
78 +
79 +export type ReactDOMListenerEvent = {|
80 + capture: boolean,
81 + passive: boolean,
82 + priority: EventPriority,
83 + type: string,
84 +|};
85 +
86 +export type ReactDOMListenerMap = {|
87 + clear: () => void,
88 + setListener: (instance: EventTarget, callback: ?(Event) => void) => void,
89 +|};
90 +
91 +export type ReactDOMListener = {|
92 + callback: Event => void,
93 + depth: number,
94 + destroy: Document | (Element => void),
95 + event: ReactDOMListenerEvent,
96 + instance: EventTarget,
97 +|};
packages/shared/ReactFeatureFlags.js
+3
@@ -60,6 +60,9 @@ export const enableFundamentalAPI = false;
60 // Experimental Scope support.
61 export const enableScopeAPI = false;
62
63 +// Experimental useEvent support.
64 +export const enableUseEventAPI = false;
65 +
66 // New API for JSX transforms to target - https://github.com/reactjs/rfcs/pull/107
67
68 // We will enforce mocking scheduler with scheduler/unstable_mock at some point. (v17?)
packages/shared/forks/ReactFeatureFlags.native-fb.js
+1
@@ -30,6 +30,7 @@ export const warnAboutDeprecatedLifecycles = true;
30 export const enableDeprecatedFlareAPI = false;
31 export const enableFundamentalAPI = false;
32 export const enableScopeAPI = false;
33 +export const enableUseEventAPI = false;
34 export const warnAboutUnmockedScheduler = true;
35 export const flushSuspenseFallbacksInTests = true;
36 export const enableSuspenseCallback = false;
packages/shared/forks/ReactFeatureFlags.native-oss.js
+1
@@ -29,6 +29,7 @@ export const enableSchedulerDebugging = false;
29 export const enableDeprecatedFlareAPI = false;
30 export const enableFundamentalAPI = false;
31 export const enableScopeAPI = false;
32 +export const enableUseEventAPI = false;
33 export const warnAboutUnmockedScheduler = false;
34 export const flushSuspenseFallbacksInTests = true;
35 export const enableSuspenseCallback = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
+1
@@ -29,6 +29,7 @@ export const enableSchedulerDebugging = false;
29 export const enableDeprecatedFlareAPI = false;
30 export const enableFundamentalAPI = false;
31 export const enableScopeAPI = false;
32 +export const enableUseEventAPI = false;
33 export const warnAboutUnmockedScheduler = false;
34 export const flushSuspenseFallbacksInTests = true;
35 export const enableSuspenseCallback = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+1
@@ -29,6 +29,7 @@ export const disableInputAttributeSyncing = false;
29 export const enableDeprecatedFlareAPI = true;
30 export const enableFundamentalAPI = false;
31 export const enableScopeAPI = true;
32 +export const enableUseEventAPI = false;
33 export const warnAboutUnmockedScheduler = true;
34 export const flushSuspenseFallbacksInTests = true;
35 export const enableSuspenseCallback = true;
packages/shared/forks/ReactFeatureFlags.testing.js
+1
@@ -29,6 +29,7 @@ export const enableSchedulerDebugging = false;
29 export const enableDeprecatedFlareAPI = false;
30 export const enableFundamentalAPI = false;
31 export const enableScopeAPI = false;
32 +export const enableUseEventAPI = false;
33 export const warnAboutUnmockedScheduler = false;
34 export const flushSuspenseFallbacksInTests = true;
35 export const enableSuspenseCallback = false;
packages/shared/forks/ReactFeatureFlags.testing.www.js
+1
@@ -29,6 +29,7 @@ export const enableSchedulerDebugging = false;
29 export const enableDeprecatedFlareAPI = true;
30 export const enableFundamentalAPI = false;
31 export const enableScopeAPI = true;
32 +export const enableUseEventAPI = false;
33 export const warnAboutUnmockedScheduler = true;
34 export const flushSuspenseFallbacksInTests = true;
35 export const enableSuspenseCallback = true;
packages/shared/forks/ReactFeatureFlags.www.js
+2
@@ -88,6 +88,8 @@ export const enableFundamentalAPI = false;
88
89 export const enableScopeAPI = true;
90
91 +export const enableUseEventAPI = false;
92 +
93 export const warnAboutUnmockedScheduler = true;
94
95 export const enableSuspenseCallback = true;