Skip to content

Commit fb2ab39

Browse files
committed
ReactDOM.useEvent: Add more scaffolding for useEvent hook
Add test
1 parent 2953425 commit fb2ab39

File tree

12 files changed

+207
-12
lines changed

12 files changed

+207
-12
lines changed

packages/react-debug-tools/src/ReactDebugHooks.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,17 @@ function useTransition(
256256
return [callback => {}, false];
257257
}
258258

259+
const noOp = () => {};
260+
261+
function useEvent(event: any): any {
262+
hookLog.push({primitive: 'Event', stackError: new Error(), value: event});
263+
return {
264+
clear: noOp,
265+
listen: noOp,
266+
unlisten: noOp,
267+
};
268+
}
269+
259270
function useDeferredValue<T>(value: T, config: TimeoutConfig | null | void): T {
260271
// useDeferredValue() composes multiple hooks internally.
261272
// Advance the current hook index the same number of times
@@ -285,6 +296,7 @@ const Dispatcher: DispatcherType = {
285296
useResponder,
286297
useTransition,
287298
useDeferredValue,
299+
useEvent,
288300
};
289301

290302
// Inspect

packages/react-dom/src/client/ReactDOMHostConfig.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ import type {
5151
ReactDOMEventResponder,
5252
ReactDOMEventResponderInstance,
5353
ReactDOMFundamentalComponentInstance,
54+
ReactDOMListener,
55+
ReactDOMListenerEvent,
56+
ReactDOMListenerMap,
5457
} from 'shared/ReactDOMTypes';
5558
import {
5659
mountEventResponder,
@@ -70,6 +73,10 @@ import {
7073
IS_PASSIVE,
7174
} from 'legacy-events/EventSystemFlags';
7275

76+
export type ReactListenerEvent = ReactDOMListenerEvent;
77+
export type ReactListenerMap = ReactDOMListenerMap;
78+
export type ReactListener = ReactDOMListener;
79+
7380
export type Type = string;
7481
export type Props = {
7582
autoFocus?: boolean,

packages/react-dom/src/events/DOMLegacyEventPluginSystem.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import {
3939
getRawEventName,
4040
mediaEventTypes,
4141
} from './DOMTopLevelEventTypes';
42-
import {trapEventForPluginEventSystem} from './ReactDOMEventListener';
42+
import {trapEventListener} from './ReactDOMEventListener';
4343

4444
/**
4545
* Summary of `DOMEventPluginSystem` event handling:
@@ -368,12 +368,12 @@ export function legacyTrapBubbledEvent(
368368
topLevelType: DOMTopLevelEventType,
369369
element: Document | Element,
370370
): void {
371-
trapEventForPluginEventSystem(element, topLevelType, false);
371+
trapEventListener(element, topLevelType, false);
372372
}
373373

374374
export function legacyTrapCapturedEvent(
375375
topLevelType: DOMTopLevelEventType,
376376
element: Document | Element,
377377
): void {
378-
trapEventForPluginEventSystem(element, topLevelType, true);
378+
trapEventListener(element, topLevelType, true);
379379
}

packages/react-dom/src/events/DOMModernPluginEventSystem.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type {EventSystemFlags} from 'legacy-events/EventSystemFlags';
1313
import type {Fiber} from 'react-reconciler/src/ReactFiber';
1414
import type {PluginModule} from 'legacy-events/PluginModuleType';
1515
import type {ReactSyntheticEvent} from 'legacy-events/ReactSyntheticEventType';
16+
import type {ReactDOMListener} from 'shared/ReactDOMTypes';
1617

1718
import {registrationNameDependencies} from 'legacy-events/EventPluginRegistry';
1819
import {batchedEventUpdates} from 'legacy-events/ReactGenericBatching';
@@ -21,7 +22,7 @@ import {plugins} from 'legacy-events/EventPluginRegistry';
2122

2223
import {HostRoot, HostPortal} from 'shared/ReactWorkTags';
2324

24-
import {trapEventForPluginEventSystem} from './ReactDOMEventListener';
25+
import {trapEventListener} from './ReactDOMEventListener';
2526
import getEventTarget from './getEventTarget';
2627
import {getListenerMapForElement} from './DOMEventListenerMap';
2728
import {
@@ -149,11 +150,7 @@ export function listenToTopLevelEvent(
149150
): void {
150151
if (!listenerMap.has(topLevelType)) {
151152
const isCapturePhase = capturePhaseEvents.has(topLevelType);
152-
trapEventForPluginEventSystem(
153-
rootContainerElement,
154-
topLevelType,
155-
isCapturePhase,
156-
);
153+
trapEventListener(rootContainerElement, topLevelType, isCapturePhase);
157154
listenerMap.set(topLevelType, null);
158155
}
159156
}
@@ -196,7 +193,7 @@ function willDeferLaterForFBLegacyPrimer(nativeEvent: any): boolean {
196193
if (node.tagName === 'A' && validFBLegacyPrimerRels.has(node.rel)) {
197194
const legacyFBSupport = true;
198195
const isCapture = nativeEvent.eventPhase === 1;
199-
trapEventForPluginEventSystem(
196+
trapEventListener(
200197
document,
201198
((type: any): DOMTopLevelEventType),
202199
isCapture,
@@ -300,3 +297,11 @@ export function dispatchEventForPluginEventSystem(
300297
),
301298
);
302299
}
300+
301+
export function attachElementListener(listener: ReactDOMListener): void {
302+
// TODO
303+
}
304+
305+
export function detachElementListener(listener: ReactDOMListener): void {
306+
// TODO
307+
}

packages/react-dom/src/events/ReactDOMEventListener.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ export function removeActiveResponderEventSystemEvent(
140140
}
141141
}
142142

143-
export function trapEventForPluginEventSystem(
143+
export function trapEventListener(
144144
container: Document | Element,
145145
topLevelType: DOMTopLevelEventType,
146146
capture: boolean,

packages/react-dom/src/events/__tests__/DOMModernPluginEventSystem-test.internal.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,4 +1039,35 @@ describe('DOMModernPluginEventSystem', () => {
10391039
expect(log).toEqual([]);
10401040
expect(onDivClick).toHaveBeenCalledTimes(0);
10411041
});
1042+
1043+
describe('ReactDOM.useEvent', () => {
1044+
beforeEach(() => {
1045+
jest.resetModules();
1046+
ReactFeatureFlags = require('shared/ReactFeatureFlags');
1047+
ReactFeatureFlags.enableModernEventSystem = true;
1048+
ReactFeatureFlags.enableUseEventAPI = true;
1049+
1050+
React = require('react');
1051+
ReactDOM = require('react-dom');
1052+
Scheduler = require('scheduler');
1053+
ReactDOMServer = require('react-dom/server');
1054+
});
1055+
1056+
it('should create the same event listener map', () => {
1057+
let listenerMaps = [];
1058+
1059+
function Test() {
1060+
const listenerMap = ReactDOM.unstable_useEvent('click');
1061+
1062+
listenerMaps.push(listenerMap);
1063+
1064+
return <div />;
1065+
}
1066+
1067+
ReactDOM.render(<Test />, container);
1068+
ReactDOM.render(<Test />, container);
1069+
expect(listenerMaps.length).toEqual(2);
1070+
expect(listenerMaps[1]).toEqual(listenerMaps[1]);
1071+
});
1072+
});
10421073
});

packages/react-dom/src/server/ReactPartialRendererHooks.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,13 @@ function useTransition(
474474
return [startTransition, false];
475475
}
476476

477+
function useEvent(event: any): any {
478+
return {
479+
clear: noop,
480+
setListener: noop,
481+
};
482+
}
483+
477484
function noop(): void {}
478485

479486
export let currentThreadID: ThreadID = 0;
@@ -500,4 +507,5 @@ export const Dispatcher: DispatcherType = {
500507
useResponder,
501508
useDeferredValue,
502509
useTransition,
510+
useEvent,
503511
};

packages/react-native-renderer/src/ReactFabricHostConfig.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ export type UpdatePayload = Object;
7676
export type TimeoutHandle = TimeoutID;
7777
export type NoTimeout = -1;
7878

79+
export type ReactListenerEvent = Object;
80+
export type ReactListenerMap = Object;
81+
export type ReactListener = Object;
82+
7983
// TODO: Remove this conditional once all changes have propagated.
8084
if (registerEventHandler) {
8185
/**

packages/react-native-renderer/src/ReactNativeHostConfig.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ import ReactNativeFiberHostComponent from './ReactNativeFiberHostComponent';
2626

2727
const {get: getViewConfigForType} = ReactNativeViewConfigRegistry;
2828

29+
export type ReactListenerEvent = Object;
30+
export type ReactListenerMap = Object;
31+
export type ReactListener = Object;
32+
2933
export type Type = string;
3034
export type Props = Object;
3135
export type Container = number;

0 commit comments

Comments
 (0)