Skip to content

Commit

Permalink
ReactDOM.useEvent add flag and entry point
Browse files Browse the repository at this point in the history
fxi
  • Loading branch information
trueadm committed Mar 10, 2020
1 parent 704c8b0 commit fb321da
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 0 deletions.
3 changes: 3 additions & 0 deletions packages/react-dom/src/client/ReactDOM.js
Expand Up @@ -20,6 +20,7 @@ import {
unmountComponentAtNode,
} from './ReactDOMLegacy';
import {createRoot, createBlockingRoot, isValidContainer} from './ReactDOMRoot';
import {useEvent} from './ReactDOMUseEvent';

import {
batchedEventUpdates,
Expand Down Expand Up @@ -218,6 +219,8 @@ export {
// Temporary alias since we already shipped React 16 RC with it.
// TODO: remove in React 17.
unstable_createPortal,
// enableUseEventAPI
useEvent as unstable_useEvent,
};

const foundDevTools = injectIntoDevTools({
Expand Down
74 changes: 74 additions & 0 deletions packages/react-dom/src/client/ReactDOMUseEvent.js
@@ -0,0 +1,74 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import type {EventPriority} from 'shared/ReactTypes';
import type {
ReactDOMListenerEvent,
ReactDOMListenerMap,
} from 'shared/ReactDOMTypes';

import ReactSharedInternals from 'shared/ReactSharedInternals';
import invariant from 'shared/invariant';

import {getEventPriorityForListenerSystem} from '../events/DOMEventProperties';

type EventOptions = {|
capture?: boolean,
passive?: boolean,
priority?: EventPriority,
|};

const {ReactCurrentDispatcher} = ReactSharedInternals;

function resolveDispatcher() {
const dispatcher = ReactCurrentDispatcher.current;
invariant(
dispatcher !== null,
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
' one of the following reasons:\n' +
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
'2. You might be breaking the Rules of Hooks\n' +
'3. You might have more than one copy of React in the same app\n' +
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
);
return dispatcher;
}

export function useEvent(
type: string,
options?: EventOptions,
): ReactDOMListenerMap {
const dispatcher = resolveDispatcher();
let capture = false;
let passive = false;
let priority = getEventPriorityForListenerSystem((type: any));

if (options != null) {
const optionsCapture = options.capture;
const optionsPassive = options.passive;
const optionsPriority = options.priority;

if (typeof optionsCapture === 'boolean') {
capture = optionsCapture;
}
if (typeof optionsPassive === 'boolean') {
passive = optionsPassive;
}
if (typeof optionsPriority === 'number') {
priority = optionsPriority;
}
}
const event: ReactDOMListenerEvent = {
capture,
passive,
priority,
type,
};
return dispatcher.useEvent(event);
}
14 changes: 14 additions & 0 deletions packages/react-dom/src/events/DOMEventProperties.js
Expand Up @@ -223,3 +223,17 @@ export function getEventPriorityForPluginSystem(
// for the event.
return priority === undefined ? ContinuousEvent : priority;
}

export function getEventPriorityForListenerSystem(type: string): EventPriority {
const priority = eventPriorities.get(((type: any): TopLevelType));
if (priority !== undefined) {
return priority;
}
if (__DEV__) {
console.warn(
'The event "type" provided to useEvent() does not have a known priority type.' +
' It is recommended to provide a "priority" option to specify a priority.',
);
}
return ContinuousEvent;
}
20 changes: 20 additions & 0 deletions packages/shared/ReactDOMTypes.js
Expand Up @@ -75,3 +75,23 @@ export type ReactDOMResponderContext = {
getResponderNode(): Element | null,
...
};

export type ReactDOMListenerEvent = {|
capture: boolean,
passive: boolean,
priority: EventPriority,
type: string,
|};

export type ReactDOMListenerMap = {|
clear: () => void,
setListener: (instance: EventTarget, callback: ?(Event) => void) => void,
|};

export type ReactDOMListener = {|
callback: Event => void,
depth: number,
destroy: Document | (Element => void),
event: ReactDOMListenerEvent,
instance: EventTarget,
|};
3 changes: 3 additions & 0 deletions packages/shared/ReactFeatureFlags.js
Expand Up @@ -60,6 +60,9 @@ export const enableFundamentalAPI = false;
// Experimental Scope support.
export const enableScopeAPI = false;

// Experimental useEvent support.
export const enableUseEventAPI = false;

// New API for JSX transforms to target - https://github.com/reactjs/rfcs/pull/107

// We will enforce mocking scheduler with scheduler/unstable_mock at some point. (v17?)
Expand Down
1 change: 1 addition & 0 deletions packages/shared/forks/ReactFeatureFlags.native-fb.js
Expand Up @@ -30,6 +30,7 @@ export const warnAboutDeprecatedLifecycles = true;
export const enableDeprecatedFlareAPI = false;
export const enableFundamentalAPI = false;
export const enableScopeAPI = false;
export const enableUseEventAPI = false;
export const warnAboutUnmockedScheduler = true;
export const flushSuspenseFallbacksInTests = true;
export const enableSuspenseCallback = false;
Expand Down
1 change: 1 addition & 0 deletions packages/shared/forks/ReactFeatureFlags.native-oss.js
Expand Up @@ -29,6 +29,7 @@ export const enableSchedulerDebugging = false;
export const enableDeprecatedFlareAPI = false;
export const enableFundamentalAPI = false;
export const enableScopeAPI = false;
export const enableUseEventAPI = false;
export const warnAboutUnmockedScheduler = false;
export const flushSuspenseFallbacksInTests = true;
export const enableSuspenseCallback = false;
Expand Down
1 change: 1 addition & 0 deletions packages/shared/forks/ReactFeatureFlags.test-renderer.js
Expand Up @@ -29,6 +29,7 @@ export const enableSchedulerDebugging = false;
export const enableDeprecatedFlareAPI = false;
export const enableFundamentalAPI = false;
export const enableScopeAPI = false;
export const enableUseEventAPI = false;
export const warnAboutUnmockedScheduler = false;
export const flushSuspenseFallbacksInTests = true;
export const enableSuspenseCallback = false;
Expand Down
Expand Up @@ -29,6 +29,7 @@ export const disableInputAttributeSyncing = false;
export const enableDeprecatedFlareAPI = true;
export const enableFundamentalAPI = false;
export const enableScopeAPI = true;
export const enableUseEventAPI = false;
export const warnAboutUnmockedScheduler = true;
export const flushSuspenseFallbacksInTests = true;
export const enableSuspenseCallback = true;
Expand Down
1 change: 1 addition & 0 deletions packages/shared/forks/ReactFeatureFlags.testing.js
Expand Up @@ -29,6 +29,7 @@ export const enableSchedulerDebugging = false;
export const enableDeprecatedFlareAPI = false;
export const enableFundamentalAPI = false;
export const enableScopeAPI = false;
export const enableUseEventAPI = false;
export const warnAboutUnmockedScheduler = false;
export const flushSuspenseFallbacksInTests = true;
export const enableSuspenseCallback = false;
Expand Down
1 change: 1 addition & 0 deletions packages/shared/forks/ReactFeatureFlags.testing.www.js
Expand Up @@ -29,6 +29,7 @@ export const enableSchedulerDebugging = false;
export const enableDeprecatedFlareAPI = true;
export const enableFundamentalAPI = false;
export const enableScopeAPI = true;
export const enableUseEventAPI = false;
export const warnAboutUnmockedScheduler = true;
export const flushSuspenseFallbacksInTests = true;
export const enableSuspenseCallback = true;
Expand Down
2 changes: 2 additions & 0 deletions packages/shared/forks/ReactFeatureFlags.www.js
Expand Up @@ -88,6 +88,8 @@ export const enableFundamentalAPI = false;

export const enableScopeAPI = true;

export const enableUseEventAPI = false;

export const warnAboutUnmockedScheduler = true;

export const enableSuspenseCallback = true;
Expand Down

0 comments on commit fb321da

Please sign in to comment.